2016-08-29 59 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进行测试) –