2

I have the following class that I am going to use for unmarshalling appropriate XML document:

 @XmlRootElement(name = "address")
 public class AddressObject {

        @XmlElement(name = "domain")
        public String domain = new String();
        @XmlElement(name = "ip-address")
        public String ipAddress = new String();
        @XmlElement(name = "user-agent")
        public String userAgent = new String();
    }

In order to unmarshall document, I use javax.xml.bind.Unmarshaller. Using code below:

JAXBContext context = JAXBContext.newInstance(AddressObject.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StreamSource streamSource = new StreamSource(new StringReader(SOME_CORRECT_XML_DOC));
JAXBElement<AddressObject> obj = unmarshaller.unmarshal(streamSource, AddressObject.class);

It works fine as long as incorrect xml uses, like below:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><hello-world></hello-world>

In the last case xml unmarshall without any errors.

Can someone explain why it's happening? I have expected to recieve any errors regarding invalid tags or something like this.

fashuser
  • 2,152
  • 3
  • 29
  • 51
  • I think that's because by default JAXB treats public fields and properties as mapped. If you annotate a field it then considers the field and property as mapped causing the conflict. Without `@XmlAccessorType(XmlAccessType.FIELD)` you should annotate the get or set method. **For More Information** - http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html – stacky Oct 27 '14 at 09:03

1 Answers1

2

First of all, JAXB does not validate on its own. You have to specify the schema if you want to turn on the validation:

Validating against a Schema with JAXB

JAXB is not strict on mappings. It takes what it can map according to the annotations and ignores the rest. Also the order of elements is not significant on unmarshalling.

I was a long term JAXB 1.x user. JAXB 1.x was very strict. I am extremely glad that JAXB 2 is not so strict.

Next, if you use

unmarshaller.unmarshal(streamSource, AddressObject.class);

you basically ignore the root element mapping as you specify the target class explicitly. That is, your hello-world is accepted as the root element despite it does not match the address in your AddressObject.

So all of this is valid and expected behavior.

Community
  • 1
  • 1
lexicore
  • 42,748
  • 17
  • 132
  • 221