16
votes

I want to create a xml from a html form with the help of a Spring MVC ModelAttribute (Person) and Jackson.

form:

....
<input name="name"/>
<input name="birthday"/>
<input name="address.street/>
<input name="address.city/>
....

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
}

create XML in Controller:

@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";
}

output xml:

    <person>
        <name>John</name>
        <email>[email protected]</email>
        <address/>
    </person>

How can i exclude the empty Objects from XML?

I tried to set all empty strings in the ModelAttribute to null:

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

But it doesn't work. I also tried @JsonInclude(Include.NON_EMPTY) and @JsonInclude(Include.NON_NULL) But it always includes empty objects in the XML.

My second question is: When i want to bind a list of addresses to the html form. What is the best way to do this?

....
<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

}

Thanks!

1

1 Answers

33
votes

ChrisIsHere!

I just ran into this issue and was happy to see someone had asked the same question but sad that no one had responded.

After tinkering, I found two possible solutions for your first question regarding not including empty values in XML output.

First was including @JsonInclude(JsonInclude.Include.NON_EMPTY) on top of my model. So for you, in this situation, I would suspect this would work:

@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 
}

This does away with your previous Include.NON_DEFAULT, which I hope you can live without if you go this route.

Second, there also appeared to be an alternative solution that I did not go with, which would have us altering the XmlMapper directly like this:

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

I hope one of these helps, ten months late.