Java Hobby (36 reads)
Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects.
JAXB2 is a very good reference implementation of the specification.
There are 2 main approaches to work with XML binding:
a)start with a
XSD schema definition as input and generate a collection of Java classes from the given XML schema through the
schema compiler.
b)start with writing the Java model classes, mark the classes with specific JAXB 2.0 annotations and compile the model classes using JAXB2 in the classpath.
Here I will demonstrate the last approach as I find much easy for myself to think in "java classes" than to write a XSD schema definition file. The scope is to write the XML binding code for the following document:
<?xml version="1.0" encoding="utf-8"?>
<documentburster>
<settings>
<defaultfilename>defaultBurst</defaultfilename>
<emailserver>
<host>your_email_server</host>
<port>your_email_port</port>
<userid>your_email_user_id</userid>
<userpassword>your_email_password</userpassword>
<usessl>false</usessl>
<usetls>false</usetls>
<debug>false</debug>
<keyfile />
<rootcertfile />
<servercertfile />
<emailaddressfrom>your_email_address</emailaddressfrom>
<emailaddressfromlabel>your_name</emailaddressfromlabel>
</emailserver>
<defaultemailmessage>
<emailmessage>
Default Message
</emailmessage>
<emailsubject>
Default Subject
</emailsubject>
</defaultemailmessage>
</settings>
</documentburster>
All the Java mapping classes are in package burster.settings.model;
First step is to write the "documentburster" root class. Here is the code:
package burster.settings.model;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="documentburster")
public class DocumentBursterSettings {
@XmlElement(name = "settings")
public BursterSettings settings;
}
I think the code is self explanatory with
@XmlRootElement(name="documentburster") the most important thing to notice. <settings> is a child for the root so the
@XmlElement(name = "settings") annotation is used. The code for the class BursterSettings is:
package burster.settings.model;
import javax.xml.bind.annotation.XmlElement;
public class BursterSettings {
@XmlElement(name = "defaultfilename")
public String defaultFileName;
@XmlElement(name = "emailserver")
public EmailServer emailServer;
@XmlElement(name = "defaultemailmessage")
public DefaultEmailMessage defaultEmailMessage;
}
EmailServer and DefaultEmailMessage are classic plain java bean classes with getters and setters and without any annotation inside. Because of space issues I will show only the code for DefaultEmailMessage.java
package burster.settings.model;
public class DefaultEmailMessage {
private String emailsubject;
private String emailmessage;
public String getEmailmessage() {
return emailmessage;
}
public void setEmailmessage(String emailmessage) {
this.emailmessage = emailmessage;
}
public String getEmailsubject() {
return emailsubject;
}
public void setEmailsubject(String emailsubject) {
this.emailsubject = emailsubject;
}
}
The code for EmailServer class is very simple as it is a plain java bean class with getters and setters.
But where is the Unmarshaller code? Where is the code that actually reads/write into the XML file? The final piece of the code is the class Settings which is a "facade" for all my model XML binding classes. From my application I access all the XML binding through the Settings class and not through each model class individually . Here is the code for Settings.java:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import burster.settings.model.BursterSettings;
import burster.settings.model.DefaultEmailMessage;
import burster.settings.model.DocumentBursterSettings;
import burster.settings.model.EmailServer;
public class Settings {
private static Settings instance = new Settings();
private DocumentBursterSettings docSettings;
private Settings(String xmlSettingsFile) {
loadSettings( xmlSettingsFile );
}
public static Settings getInstance() {
return instance;
}
public void loadSettings(String xmlSettingsFile )
{
try {
JAXBContext jc = JAXBContext.newInstance(DocumentBursterSettings.class);
Unmarshaller u = jc.createUnmarshaller();
docSettings = (DocumentBursterSettings)u.unmarshal(new File( xmlSettingsFile ));
} catch(Exception e){
System.out.println("Settings.loadSettings: " + e);
}
}
private BursterSettings getSettings() {
return docSettings.settings;
}
public EmailServer getEmailServer() {
return getSettings().emailServer;
}
public DefaultEmailMessage getDefaultEmailMessage() {
return getSettings().defaultEmailMessage;
}
public String getDefaultFileName() {
return getSettings().defaultFileName;
}
}
In this post I experimented only with a small part of what JAXB2 is capable. By the way JAXB2 is included with Java SE6 but you can use it in earlier versions of Java if you download it from
here.
I would appreciate a comment if you feel you have your own noteworthy xml binding tips.
Further resources:
1)
DocumentBurster project2)
Another Good JAXB2 tutorial3)
XML Data Binding Resources