2016-08-29 67 views
1

我想重寫一些API序列化從自定義映射器到基於註釋的樣式,並面臨一個硬映射(這是先前自定義序列化爲json和xml分開),我不能「翻譯成。 (序列化與傑克遜進行。)Java春天。棘手的序列化到json和xml的註解

在POJO中,我們有一個集合,例如,

class Data { 
    Set<Integer> tags; 
} 

應在XML序列化,如:

<tags> 
    <tag id="1"/> 
    <tag id="2"/> 
</tags> 

和JSON,如:

{ 
    "tags":[1,2] 
} 

海峽法

@XmlElementWrapper(name="tags") 
@XmlElement(name="tag") 

提供良好的JSON,但不正確的xml像

<root> 
    <tags> 
     <tag>1<tag/> 
     <tag>2<tag/> 
    </tags> 
</root> 

因爲沒有屬性說明。

我試着換了一下有:

class Data{ 
    @XmlElementWrapper(name="tags") 
    @XmlElement(name="tag") 
    Set<Tag> tags; 
} 

class Tag{ 
    @XmlAttribute(name="id") 
    Integer id; 
} 

但這產生不需要的關鍵JSON格式,如:

"tags":[ 
    {"tag":{"id":1}}, 
    {"tag":{"id":2}} 
] 

好吧,那麼。我試圖指定自定義JSON序列化器(實現JsonSerializer和注入@JsonSerialize(使用= ...)),但似乎它也影響xml「渲染」。

是否有可能只使用註釋來完成技巧?或者MB有可能以某種方式爲某些類使用默認的json序列化和自定義的xml serializtaion? 。例如。 使用自定義XML序列化只爲理由類這樣的方式

class Data { 
    @XmlElement("tags") 
    Reasons tags; 
} 

但讓周圍所有的數據是「渲染」與總體戰略。

回答

0

只需創建一個使用@JsonValue註釋的getter將告訴Jackson生成一個沒有任何字段名稱的單個值。

這種映射:

@XmlRootElement 
public class Data{ 

    public Set<Tag> tags; 
} 

public class Tag{ 

    @XmlAttribute 
    public Integer id; 

    @JsonValue 
    public Integer getId() { 
     return id; 
    } 
} 

然後將產生:

{"tags":[2,1]} 

和:

<data><tags id="2"/><tags id="1"/></data> 

PS:您使用JAXB註釋,我不認爲傑克遜將尊重他們。 要獲得XML結果上面,你需要使用JAXB:

StringWriter writer = new StringWriter(); 
    JAXBContext context = JAXBContext.newInstance(Data.class, Tag.class); 
    Marshaller m = context.createMarshaller(); 
    m.marshal(value, writer); 
    System.out.println(writer.getBuffer().toString()); 

最後一點,我沒有使用一個單一的映射多種表示的超級粉絲。這對於簡單的東西來說可能是好的,但是如果你的代碼比這個更復雜,我強烈建議你創建兩組類(一個用於XML映射,另一個用於JSON),也許有一個通用接口。

+0

但傑克遜支持JAXB註釋,不是嗎?我的意思是xml序列化對於所有這些Xml都是正確的......但是如果我將添加JsonValue,那麼xml會放棄其屬性。 MB可以指定每個類的xml序列化嗎? – smwoody

+0

好的,我已經搜索了一下,答案是肯定的,如果你添加這個依賴:https://github.com/FasterXML/jackson-module-jaxb-annotations。你有沒有在你的項目?我的「香草」傑克遜串行器完全忽略了它們。 –

+0

(無論如何,我的解決方案僅用JSON的傑克遜ObjectMapper和用於XML的JAXB Mashaller進行測試) –