Jackson xml在序列化时忽略空对象

chr*_*ere 7 java spring-mvc jackson

我想借助Spring MVC ModelAttribute(Person)和Jackson从html表单创建一个xml.

形成:

....
<input name="name"/>
<input name="birthday"/>
<input name="address.street/>
<input name="address.city/>
....
Run Code Online (Sandbox Code Playgroud)

POJO:

@JacksonXmlRootElement(localName = "person")
@JsonInclude(Include.NON_DEFAULT)
public class Person implements Serializable {
    @JsonIgnore
    private Long id;
    @JacksonXmlProperty(localName = "name")
    private String name;
    @JacksonXmlProperty(localName = "email")
    private String email;
    @JacksonXmlProperty(localName = "address")
    private Address address;
    private String birthday;

//getter and setter

}

@JsonInclude(Include.NON_EMPTY)
public class Address implements Serializable {
    private Long id;
    private String street;
    private String streetNumber;
    private String postalcode;
    private String city;

   //getter and setter
}
Run Code Online (Sandbox Code Playgroud)

在Controller中创建XML:

@RequestMapping("saveperson")
public String savePerson(@ModelAttribute final Person person, final ModelMap model) {
    final ObjectMapper xmlMapper = new XmlMapper();
    final String xml = xmlMapper.writeValueAsString(person);
    return "redirect:/listpersons";
}
Run Code Online (Sandbox Code Playgroud)

输出xml:

    <person>
        <name>John</name>
        <email>john@test.com</email>
        <address/>
    </person>
Run Code Online (Sandbox Code Playgroud)

如何从XML中排除空对象?

我试图将ModelAttribute中的所有空字符串设置为null:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用.我还尝试了@JsonInclude(Include.NON_EMPTY)和@JsonInclude(Include.NON_NULL)但它总是包含XML中的空对象.

我的第二个问题是:当我想将地址列表绑定到html表单时.做这个的最好方式是什么?

....
<input name="name"/>
<input name="birthday"/>
<input name="address1.street/>
<input name="address1.city/>
<input name="address2.street/>
<input name="address2.city/>
....

@JacksonXmlRootElement(localName = "person")
@JsonInclude(Include.NON_DEFAULT)
public class Person implements Serializable {
    @JsonIgnore
    private Long id;
    @JacksonXmlProperty(localName = "name")
    private String name;
    @JacksonXmlProperty(localName = "email")
    private String email;
    @JsonIgnore
    private Address address1;
    @JsonIgnore
    private Address address2;
//add address1 and address2 in the getter or dto for the ModelAttribute?
    @JacksonXmlElementWrapper(localName = "addresses")
    @JacksonXmlProperty(localName = "address")
    private List<Address> address;
    private String birthday;

//getter and setter

}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Ace*_*kay 14

ChrisIsHere!

我刚刚遇到这个问题,很高兴看到有人问了同样的问题,但很遗憾没有人回应.

在修补之后,我找到了两个可能的解决方案,第一个问题是不包括XML输出中的空值.

首先是@JsonInclude(JsonInclude.Include.NON_EMPTY)在我的模型之上.所以对你来说,在这种情况下,我怀疑这会起作用:

@JacksonXmlRootElement(localName = "person") 
@JsonInclude(JsonInclude.Include.NON_EMPTY) 
public class Person implements Serializable {
    @JsonIgnore 
    private Long id;
    @JacksonXmlProperty(localName = "name") 
    private String name;
    @JacksonXmlProperty(localName = "email") 
    private String email;
    @JacksonXmlProperty(localName = "address") 
    private Address address;
    private String birthday;

   //getter and setter 
}
Run Code Online (Sandbox Code Playgroud)

这取消了你之前的Include.NON_DEFAULT,我希望如果你走这条路,你可以活下去.

其次,似乎还有一个我没有使用的替代解决方案,这将使我们直接改变XmlMapper,如下所示:

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
Run Code Online (Sandbox Code Playgroud)

我希望其中一个有所帮助,迟到十个月.