Jaxb Unmarshaller: repeated xmlelement without shell

<a> <b1>b1</b1> <b2>b2</b2> <b3> <c1></c1> <c2></c2> </b3> <b3> <c1></c1> <c2></c2> </b3> <b3> <c1></c1> <c2></c2> </b3> </a> 

Since all <b3> not included in the shell element, say <b3s> , when I use Jackson XmlMapper to read an XML file in my POJO Java Bean class, I got an exception

 com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.xxxxx] from String value; no single-String constructor/factory method (through reference chain: com.xxxx["xxx"]->com.xxx["xxx"]) 

What annotation should I use?

 @XmlElement public List<B3> b3; 
+6
source share
3 answers

Note

Jackson is not a JAXB (JSR-222) . This means that there is no guarantee as to how it interprets standard JAXB annotations.


By default, the JAXB implementation (JSR-222) does not apply the wrapper element to the properties of the collection.

A

By default, the JAXB implementation (JSR-222) will display by default based on properties. To save space, I omitted these methods and indicated @XmlAccessorType(XmlAccessType.FIELD) so that the metadata is obtained from instance variables (fields).

 package forum13097559; import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class A { private String b1; private String b2; private List<B3> b3; } 

B3

 package forum13097559; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class B3 { private String c1; private String c2; } 

Demo

 package forum13097559; import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(A.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum13097559/input.xml"); A a = (A) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(a, System.out); } } 

Input.xml / output

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <a> <b1>b1</b1> <b2>b2</b2> <b3> <c1></c1> <c2></c2> </b3> <b3> <c1></c1> <c2></c2> </b3> <b3> <c1></c1> <c2></c2> </b3> </a> 

Additional Information

+5
source

If you want to use the "expanded" view, you need to use Jackson 2.1 and specify the expanded option:

 @JacksonXmlElementWrapper(useWrapping=false) 

alternatively, if you use JAXB annotations, you should not use a wrapper by default.

Finally, you can also change the default value so as not to use a shell element with:

 JacksonXmlModule module = new JacksonXmlModule(); // to default to using "unwrapped" Lists: module.setDefaultUseWrapper(false); XmlMapper xmlMapper = new XmlMapper(module); 
+4
source

Jackson does not know how to turn a string into an instance of B3 . Add a constructor (or factory method that returns B3 )) to B3 that takes one String . Constructor example:

 class B3 { // ... public B3(String value) { // do something with value } // ... } 

http://wiki.fasterxml.com/JacksonFeatureCreators

0
source

All Articles