Jackson XML序列化生成动态子元素XML时多余元素问题求解
解决Jackson XML生成多余元素的问题
问题原因
你当前的代码中,Root类的addOrDeletePerson字段会被Jackson默认序列化为一个XML元素,再加上@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT)会为多态类型额外套一层addPerson/deletePerson元素,最终导致生成的XML出现不必要的嵌套结构。
解决方案
方案一:移除Root类,直接序列化目标对象
最简洁的方式是去掉Root类,利用XmlMapper的writerWithRootName方法直接指定根元素为root,然后序列化AddPerson或DeletePerson对象,这样就能让目标元素直接成为root的子元素:
修改后的Main.java
public class Main { static final XmlMapper xmlMapper = new XmlMapper(); public static void main(String[] args) throws JsonProcessingException { // 生成Add.xml结构 AddPerson addPerson = new AddPerson(new Person("1")); String addXml = xmlMapper.writerWithRootName("root").writeValueAsString(addPerson); System.out.println(addXml); // 生成Delete.xml结构 DeletePerson deletePerson = new DeletePerson(new Person("1")); String deleteXml = xmlMapper.writerWithRootName("root").writeValueAsString(deletePerson); System.out.println(deleteXml); } }
方案二:修改Root类的注解(保留Root类的场景)
如果必须保留Root类,只需给addOrDeletePerson字段添加@JsonUnwrapped注解,让Jackson序列化时展开该字段,不生成addOrDeletePerson元素:
修改后的Root.java
@JacksonXmlRootElement(localName = "root") public class Root { @JsonUnwrapped @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) @JsonSubTypes({ @JsonSubTypes.Type(name = "addPerson", value = AddPerson.class), @JsonSubTypes.Type(name = "deletePerson" , value = DeletePerson.class) // 修正原拼写错误:deletePeson -> deletePerson }) Object addOrDeletePerson; // 构造函数、getter、setter方法 }
注意事项
- 原代码中
@JsonSubTypes里的deletePeson是拼写错误,需修正为deletePerson,否则生成的XML元素名会出错。 - 两种方案都能生成符合预期的XML结构,最终输出如下:
<root><addPerson><person idPerson="1"/></addPerson></root> <root><deletePerson><person idPerson="1"/></deletePerson></root>
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

