16606

Custom serialization in JAXB

Question:

Is there a way to customize XML serialization in JAXB, in the same way that it's possible using IXmlSerializable in .NET? (i.e. the ability to directly control serialization of an object using the equivalent of an XmlReader/Writer).

I've taken a look at XmlAdapter and @XmlJavaTypeAdapter, but they just seem to be used to transform types to and from serializable forms, which isn't quite what I want.

Update: In particular, I'd like to customize the deserialization of a root object, that determines, programatically, exactly how to deserialize the inner XML (e.g. create a jaxb unmarshaller with a particular set of known types).

Update: I've found a way to solve the problem, but it's such a nasty hack I'll probably go with one of the solutions suggested by the other posters.

Answer1:

I'm not sure I fully understand what your goal is, but maybe you could do what you want to do programatically inside the no-args constructor of your root object, which will be called to instantiate the object when it is unmarshalled.

Answer2:

OK, so I managed to get this working, although it's such a nasty solution that I think I'll find a higher-level way of working around the problem, as Fabian and basszero have mentioned. The idea of the following code is to create a generic serializable reference to the data you want to serialize, which maintains a JAXB java type adapter to perform the serialization programmatically, and a string field that stores the resulting XML.

Note: Code has been greatly simplified for display...

// Create an instance of this class, to wrap up whatever you want to custom-serialize @XmlRootElement public static class SRef { public SRef() { } public SRef(Object ref) { this.ref = ref; } @XmlJavaTypeAdapter(SRefAdapter.class) public Object ref; } // This is the adapted class that is actually serialized public static class SRefData { // This is a hint field to inform the adapter how to deserialize the xmlData @XmlAttribute public String hint; // This contains the custom-serialized object @XmlElement public String xmlData; } // Converts an object to and from XML using a custom serialization routine public static class SRefAdapter extends XmlAdapter<SRefData, Object> { @Override public SRefData marshal(Object value) throws Exception { if (value instanceof MyType) { SRefData data = new SRefData(); data.xmlData = doSomeSpecificSerialization(value); data.hint = "myType"; return data; } throw new IllegalArgumentException("Can't serialize unknown object type " + value.getClass()); } @Override public Object unmarshal(SRefData refData) throws Exception { if (refData.hint.equals("myType")) { return doSomeSpecificDeserialization(refData.xmlData); } throw new IllegalArgumentException("Unhandled hint value in SRefData: " + refData.hint); } }

Answer3:

Sounds like you want a root node to contain two different sets of xml nodes/trees based on some sort of attribute or knowledge gained from the root node itself.

I tend to use JAXB by first creating a schema (xsd) and then generating the Java source, which I NEVER modify. I only modify the schema and regen. I realized that JAXB can't be used the other way, by annotating source, buy I can't speak to that way since I don't use it. If you you a schema ... read on

Consider this: <a href="http://www.w3schools.com/Schema/schema_complex_indicators.asp" rel="nofollow">http://www.w3schools.com/Schema/schema_complex_indicators.asp</a>

Rather than switching the unmarshaller, just include both xml definitions. They will be get parsed regardless and you can vary you program control flow via whatever attribute you would check on the root node.

Recommend

  • R Shiny: User defined function works well in regular R code but fails inside a shiny function
  • Parse dev/input/event touch events
  • Whats the best way of persisting data to Isolated Storage on Windows Phone 7?
  • MultiLevel ExpandableListView not highlighting properly
  • INSERT EXEC Statement cannot be nested [duplicate]
  • Double dispatch in Java example
  • How to display special characters in SQL server 2008?
  • How to use function wrapper in mustache.php?
  • Fail:(TESTMODE) Transactions of this market type cannot be processed on this system
  • as3-flash: any way to access all the instances placed in different frames from document class?
  • GAE: Way to get reference to an HttpSession from its ID?
  • Do I need to seed any random number generator before using EVP_PKEY_keygen of OpenSSL?
  • Spring boot 2.0.0.M4 required a bean named 'entityManagerFactory' that could not be found
  • What is the purpose of TaskExecutor in spring?
  • Get history of file changes from TFS to implement custom “blame”-behaviour of exceptions
  • Remove final comma from string in vb.net
  • Create DicomImage from scratch using Dcmtk
  • Installed module is empty
  • How to get Eclipse Oxygen to run on Java 9
  • Custom Tabgroup Appcelerator
  • iOS: Detect app start via notification press
  • How to do unit test for HttpContext.Current.Server.MapPath
  • Initializer list vs. initialization method
  • Control modification in presentation layer
  • Is there a javascript serializer for JSON.Net?
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Read text file and split every line in MSBuild
  • C# - Serializing and deserializing static member
  • Can Jackson SerializationFeature be overridden per field or class?
  • Java applet as stand-alone Windows application?
  • Redux, normalised entities and lodash merge
  • Android Studio and gradle
  • Error creating VM instance in Google Compute Engine
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • How can I remove ASP.NET Designer.cs files?
  • Is it possible to post an object from jquery to bottle.py?
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app
  • java string with new operator and a literal