JAXB unmarshalling of a XML file into objects works fine when run in testng unit testcase.
When the same code is used to unmarshall the same XML file in another process, I am getting an empty object. I could verify that objects are getting created for every element in the XML document and all the adapters are getting called. Set the event handler in unmarshaller but there were no validation issues. When I set the xmlns attribute and the prefix, the behavior was slightly different even though empty object is returned.
I saw several posts but could not relate with the problem I am facing.
Please suggest where I should start looking for the problem. Is it mandatory to specify schema when unmarshalling?
The cause is mentioned in this post: JAXB does not call Setter method.
Confirmed that the get method for the list is getting called and is populated.
Replaced the list with an array and the problem was solved.
The beauty of JAXB is it doesnot call the setter and it uses the same List from ther getter. In case of generating JAXB classes from XSD; you can even notice that the elements with maxOccurs=unbound required=true will not have a setter at all.
Related
I am using jaxb moxy unmarshalling, and my java object has some logic in getter methods to set values in Array. so facing issue in unmarshalling, as the getter method is invoked twice by jaxb framework while unmarshalling. is there any way to avoid this getter method being called twice? can some thing be set in binding xml to avoid this getter call for null check?
You could specify #XmlAcessorType(XmlAccessType.FIELD) so that MOXy (or and JAXB implementation) uses the field directly instead of the property (get/set methods). With this access type you will want to put the annotations on the fields.
For More Information
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
I've been using Metro and have come across a problem whereby wsgen seems to ignore any JAXB annotation that I put on web method response classes.
I'm trying to return a set of entity classes that I want to expose to external clients via a web service, however I only want to make certain class attributes and methods visible to external clients, so have set the class access type to be PROPERTY, and have annotated all attributes I want to be part of the XML version of the class with #XmlElement.
I can create the XML schema for the entity class using the schemagen ant task, which correctly ignores any attribute or method that I have not annotated with #XmlElement, however when I run wsgen to create the wsdl for the web service which has a method which returns a set of the entity class, then I get a java.lang.NoClassDefFoundError. This appears to be because wsgen is not ignoring a public method on the entity class that it should do, with the class referenced by the exception being a parameter to this method.
I've tried to annotate the method with #XmlTransient so that wsgen ignores it, but to no avail. If anyone can suggest what I should do to get wsgen to pay attention to my annotations then that would be great.
An annotated field/property will always be processed regardless of accessor type. You need to specify #XmlAccessorType(XmlAccessType.NONE) if you only want annotated fields/properties to be treated as mapped.
For More Information
http://blog.bdoughan.com/2012/04/jaxb-and-unmapped-properties.html
We are using Castor to unmarshall the Castor object to XML string. Castor is not generating Empty tags for null objects. Is there a API available to set it as parameter while unmarshalling?
There is a way to handle it by using the handler and override convertUponGet method to return empty string. But, Is there a better to do it?
Any clues will help.
From what I have seen there are 3 ways of dealing with this in order of best to worst.
Use a GeneralizedFieldHandler as explained in http://stackoverflow.com/questions/9176479/how-to-tell-castor-to-marshall-a-null-field-to-an-empty-tag. The field handler is reusable for other fields and doesn't change the behavior of your class.
Modify your get method for the given field to check for nulls and return an empty string if it is null. This approach changes the behavior of your class so if you have other parts of your code relying on nulls for this field, which also isn't a good idea, you will run into problems.
Modify Castor yourself to return an empty string when a null is encountered. Usually a really bad idea changing a tool you are using, unless you submit it back to the developers of the project to integrate into their code base for future releases. This doesn't seem likely since this issue was brought up back in 2007 http://old.nabble.com/Forcing-marshalling-of-null-empty-values--to9080721.html#a9096375 if not earlier
I have a very basic application that uses JAXB marshaller to validate input information against an xsd schema. I register a validation event handler to obtain information about the exceptions. What I would like to achieve is the ability to include this information into xml output structure I receive as a result of marshaling. I’ve included exception collection section into my xsd and now I can instantiate the corresponding exception object once an exception is encountered. The question is how do I attach this object to the rest of my JAXB generated Java objects structure considering the fact that marshaling process had already started? Is it even possible? Or should I try and modify the xml result after the marshaling is done? Any advice would be highly appreciated.
Thanks!
There a couple of ways to do this:
Option #1 - Add an "exceptions" Property to You Root Object
Ensure that the exceptions property is marshalled last, this can be configured using propOrder on the #XmlType annotation.
Create a validation handler that holds onto the root object.
When the validation handler encounters an exception, add that exception to the exceptions property on the root object.
Option #2 - Use an XMLStreamWriter
Create an XMLStreamWriter
Write out a root element
Set the validation handler on the marshaller, ensure that it will store the exceptions encountered.
Marshal the root object to the XMLStreamWriter.
Marshal the individual exceptions encountered to the XMLStreamWriter.
Write out the close for the root element.
Short answer: no. JAXB is intended to take an object graph and produce XML. it's not intended to do this.
Longer answer: You could inject the exception representation into the graph after JAXB is done the first time.
Even longer answer: There are a number of plugin and customization technologies for JAX-B, and it's possible that you could use one of them. However, it's very hard to conceptualize this at the abstract level of your question.
When marshaling some objects into XML, I need to insert an additional field in each of the resulting XML objects - sort of flag. The purpose is not modifying the source objects but inserting that information in the output XML.
Any ideas if this is possible?
There are a few possible approaches:
1. Use an XmlAdapter
You could leverage JAXB's XmlAdapter. Here you would create a version of the classes with the extra field (the adapted classes could extend the original). Then convert between them in the adapter. Since the alternate version of the class would contain the extra field it would marshal out.
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
2. Use Binder
If you marshal target is DOM, then you could leverage JAXB's Binder. It is intended for infoset preservation, but after a marshal it does maintain a link between the objects and the DOM nodes. Once the marshal is complete you could use the binder to find an object's associated node and update it.
http://bdoughan.blogspot.com/2010/09/jaxb-xml-infoset-preservation.html
3. Wrap the Output Target
If your output target is something like a ContentHandler or XMLStreamWriter then when the appropriate state is reached you could trigger additional events to be called on the nested marshal target.
The easiest way I can think of would be to use JAXB to marshal to a DOM, and then programmatically insert your extra information into that DOM, then re-marshal the DOM to XML.
Ugly and inefficient, but that's the best I can think of.