XML serialization in Java?
Back in the golden XML days, I worked some projects that used similar processes to generate Java code from XML definitions. Solution 2: XStream is pretty good at serializing object to XML without much configuration and money!
XML serialization in Java?
2008 Answer The «Official» Java API for this is now JAXB — Java API for XML Binding. See Tutorial by Oracle. The reference implementation lives at http://jaxb.java.net/
2018 Update Note that the Java EE and CORBA Modules are deprecated in SE in JDK9 and to be removed from SE in JDK11. Therefore, to use JAXB it will either need to be in your existing enterprise class environment bundled by your e.g. app server, or you will need to bring it in manually.
XStream is pretty good at serializing object to XML without much configuration and money! (it’s under BSD license).
We used it in one of our project to replace the plain old java-serialization and it worked almost out of the box.
«Simple XML Serialization» Project
You may want to look at the Simple XML Serialization project. It is the closest thing I’ve found to the System.Xml.Serialization in .Net.
Examples of XML Serialization, The following code examples address various advanced scenarios, including how to use XML serialization to generate an XML stream that conforms to a specific XML Schema (XSD) document. Serializing a DataSet. Besides serializing an instance of a public class, an instan…Serializing A DatasetBesides serializing an instance of a public class, an instance of a DataSetcan also be serialized, as shown in the following code example.Serializing An Xmlelement and XmlnodeYou can also serialize instances of an XmlElement or XmlNodeclass, as shown in the following code example.Serializing A Class That Contains A Field Returning A Complex ObjectIf a property or field returns a complex object (such as an array or a class instance), the XmlSerializerconverts it to a…Serializing An Array of ObjectsYou can also serialize a field that returns an array of objects, as shown in the following code …Serializing A Class That Implements The iCollection InterfaceYou can create your own collection classes by implementing the ICollection interface, and us…Purchase Order ExampleYou can cut and paste the following example code into a text file renamed with a .cs or .vb file name extension. Use the C# or Visual Basic compiler to com…See Also1. 2. 3. Code sample(object sender, XmlAttributeEventArgs e)
12.4 Serialization of Java Object in XML using
Saving the state of an object in a file is known as serialization . Rather than serializing Java objects to binary format we can serialize them to XML documen
How to add an XML namespace (xmlns) when serializing an object to XML
XStream doesn’t support namespaces but the StaxDriver it uses, does. You need to set the details of your namespace into a QNameMap and pass that into the StaxDriver :
QNameMap qmap = new QNameMap(); qmap.setDefaultNamespace("http://libvirt.org/schemas/domain/qemu/1.0"); qmap.setDefaultPrefix("qemu"); StaxDriver staxDriver = new StaxDriver(qmap); XStream xstream = new XStream(staxDriver); xstream.autodetectAnnotations(true); xstream.alias("domain", Domain.class); Domain d = new Domain("kvm","linux"); String xml = xstream.toXML(d);
Alternatively, this use case could be handled quite easily with a JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc):
package com.example; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Domain < private String type; private String os; @XmlAttribute public String getType() < return type; >public void setType(String type) < this.type = type; >public String getOs() < return os; >public void setOs(String os) < this.os = os; >>
package-info
@XmlSchema(xmlns=< @XmlNs( prefix="qemu", namespaceURI="http://libvirt.org/schemas/domain/qemu/1.0") >) package com.example; import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlSchema;
package com.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; public class Demo < public static void main(String[] args) throws JAXBException < JAXBContext jc = JAXBContext.newInstance(Domain.class); Domain domain = new Domain(); domain.setType("kvm"); domain.setOs("linux"); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(domain, System.out); >>
For More Information
- http://bdoughan.blogspot.com/2010/08/jaxb-namespaces.html
- http://bdoughan.blogspot.com/2010/10/how-does-jaxb-compare-to-xstream.html
This is a bit of a hack, but it’s quick and easy: add a field to your class called xmlns , and only have it non-null during serialisation. To continue your example:
@XStreamAlias(value="domain") public class Domain < @XStreamAsAttribute private String type; private String os; (. ) @XStreamAsAttribute @XStreamAlias("xmlns:qemu") String xmlns; public void serialise(File path) < XStream xstream = new XStream(new DomDriver()); xstream.processAnnotations(Domain.class); (. ) PrintWriter out = new PrintWriter(new FileWriter(path.toFile())); xmlns = "http://libvirt.org/schemas/domain/qemu/1.0"; xstream.toXML(this, out); xmlns = null; >>
To be complete, setting xmlns = null should be in a finally clause. Using a PrintWriter also allows you to insert an XML declaration at the start of the output, if you like.
XML serialization in Java?, 0. If you’re talking about automatic XML serialization of objects, check out Castor: Castor is an Open Source data binding framework for Java [tm]. It’s the shortest path between Java objects, XML documents and relational tables. Castor provides Java-to-XML binding, Java-to-SQL persistence, and more.
Converting an XML serialization back to java code
Provided that all serialized objects comply to the java beans contract, you can re-create the process that the XML de-serializer follows to unmarshal the java objects, in order to recreate the code that goes with it.
Back in the golden XML days, I worked some projects that used similar processes to generate Java code from XML definitions.
Departing from your serialized model, you can use a XSL-T transformation to recreate the code that lead to the serialized objects. This process will create very linear code (as in non-modular), but you’ll have what you’re looking for.
An example to get you started: To process the XML you provided, you can use the following recursive transformation: copy/paste it & try it here: online XSL-T (the template is based on Xpath 1.0 to be able to use the online tool. Xpath 2.0 will improve the code in some areas, like string functions)
Disclaimer: I tested the template on the sample provided and some variations of it, including some containign several more objects. I did not test deeper object nesting. It’s an example and not a fully-functional XML Serialization to Java transformation, which is left as an exercise to the reader 🙂
Yes, I think there are several ways to implement this. First of all you can use JAXB technology, read about it http://www.oracle.com/technetwork/articles/javase/index-140168.html#xmp1. Second way: you always can read xml in runtime (DOM, SAX) and create objects dynamically using reflection.
I don’t think this is possible because if object class can be everything, how would you know what method to call to set size x to 42? Maybe there is a setter for this, maybe just a constructor or the number was calculated somehow.
The only possibility I can imagine is through the use of reflection, that’s more or less the same frameworks like XStream do. So you can create the same object, but not the same code that was originally used to create it.
XMLEncoder in java for serialization, // It then loads from the XML file into a new ArrayList // // Keywords: ArrayList, Serialize, XMLEncode, XMLDecode // Note: Change the XML file while the 10 second Thread.sleep is waiting to see that // …
Serialize Java Object to XML using XMLEncoder
Default java serialization converts the java objects into bytes to send over the network. But many times we will need a more cross-platform medium to send this information e.g. XML so that applications working on different technologies can also gain the advantage of this serialized information. In this example, we will learn to serialize the java objects into XML files and then de-serialize them back to the original java objects.
To demonstrate the usage, we have created a class UserSettings with 3 fields which we will serialize to XML and then de-serialize XML to java object.
public class UserSettings < private Integer fieldOne; private String fieldTwo; private boolean fieldThree; //constructors, setters, getters >
Let’s first see the example of XMLEncoder class which is used to serialize or encode a java object into an XML file.
private static void serializeToXML (UserSettings settings) throws IOException < FileOutputStream fos = new FileOutputStream("settings.xml"); XMLEncoder encoder = new XMLEncoder(fos); encoder.setExceptionListener(new ExceptionListener() < public void exceptionThrown(Exception e) < System.out.println("Exception! :"+e.toString()); >>); encoder.writeObject(settings); encoder.close(); fos.close(); >
XMLEncoder use reflection to find out what fields they contain, but instead of writing them in binary, they are written in XML. Objects that are to be encoded don’t need to be Serializable, but they do need to follow the Java Beans specification e.g.
- The object has a public empty (no-arg) constructor.
- The object has public getters and setters for each protected/private property.
Running the above code will generate the XML file with the below content:
Please note that if the default value of a property hasn’t changed in the object to be written, the XmlEncoder will not write it out. For example, in our case fieldThree is of type boolean which has default value as false – so it has been omitted from XML content. This allows the flexibility of changing what a default value is between versions of the class.
3. Deserialize XML to POJO
Now let’s see an example of XMLDecoder which has been used to deserialize the XML file back to a java object.
private static UserSettings deserializeFromXML() throws IOException
The XMLEncoder and XMLDecoder is much more forgiving than the serialization framework. When decoding, if a property changed its type, or if it was deleted/added/moved/renamed, the decoding will decode “as much as it can” while skipping the properties that it couldn’t decode.
Let’s see the whole example of using XMLEncoder and XMLDecoder .
import java.beans.ExceptionListener; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class XMLEncoderDecoderExample < public static void main(String[] args) throws IOException < UserSettings settings = new UserSettings(); settings.setFieldOne(10000); settings.setFieldTwo("HowToDoInJava.com"); settings.setFieldThree(false); //Before System.out.println(settings); serializeToXML ( settings ); UserSettings loadedSettings = deserializeFromXML(); //After System.out.println(loadedSettings); >private static void serializeToXML (UserSettings settings) throws IOException < FileOutputStream fos = new FileOutputStream("settings.xml"); XMLEncoder encoder = new XMLEncoder(fos); encoder.setExceptionListener(new ExceptionListener() < public void exceptionThrown(Exception e) < System.out.println("Exception! :"+e.toString()); >>); encoder.writeObject(settings); encoder.close(); fos.close(); > private static UserSettings deserializeFromXML() throws IOException < FileInputStream fis = new FileInputStream("settings.xml"); XMLDecoder decoder = new XMLDecoder(fis); UserSettings decodedSettings = (UserSettings) decoder.readObject(); decoder.close(); fis.close(); return decodedSettings; >>
UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false] UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false]
Drop me your questions in the comments section.