A JAXB example

Let's create a Maven project to try out JAXB APIs. Select the File | Maven Project menu:

Figure 9.1: Create a Maven project for a JAXB example

Make sure that the project is configured to use JRE 1.7 or later. Let's now create two classes, Course and Teacher. We want to serialize instances of these classes to XML and back. Create these classes in the packt.jee.eclipse.jaxb.example package. Here is the source code of the Course class:

package packt.jee.eclipse.jaxb.example; 
//Skipped imports 
 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Course { 
  @XmlAttribute 
  private int id; 
  @XmlElement(namespace="http://packt.jee.eclipse.jaxb.example") 
  private String name; 
  private int credits; 
  @XmlElement(name="course_teacher") 
  private Teacher teacher; 
 
  public Course() {} 
 
  public Course (int id, String name, int credits) { 
    this.id = id; 
    this.name = name; 
    this.credits = credits; 
  } 
 
  //Getters and setters follow 
} 

When a Course is marshalled to an XML document, we want the course element to be the root. Therefore, the class is annotated with @XmlRootElement.


Marshalling is the process of writing the data, typically an object, to a format link XML or JSON. Unmarshalling is the process of reading the data from a format and creating an object.

You can specify a different name for the root element (other than the class name) by specifying the name attribute, for example:

@XmlRootElement(name="school_course") 

The id field is marked as an attribute of the root element. You don't have to mark fields specifically as elements if there are public getters/setters for them. However, if you want to set additional attributes, then you need to annotate them with @XmlElement. For example, we have specified a namespace for the name field. The credits field is not annotated, but it will still be marshalled as an XML element.

Here is the source code for the Teacher class:

package packt.jee.eclipse.jaxb.example; 
 
public class Teacher { 
  private int id; 
  private String name; 
 
  public Teacher() {} 
 
  public Teacher (int id, String name) { 
    this.id = id; 
    this.name = name; 
  } 
 
  //Getters and setters follow 
} 

We are not annotating the Teacher class for JAXB because we are not going to marshal it directly. It will be marshalled by JAXB when an instance of Course is marshalled.

Let's create the JAXBExample class with the main method:

package packt.jee.eclipse.jaxb.example; 
 
//Skipped imports 
 
public class JAXBExample { 
 
  public static void main(String[] args) throws Exception { 
    doJAXBXml(); 
 
  } 
 
  //Create XML from Java object and then vice versa 
  public static void doJAXBXml() throws Exception { 
    Course course = new Course(1,"Course-1", 5); 
    course.setTeacher(new Teacher(1, "Teacher-1")); 
 
    JAXBContext context = JAXBContext.newInstance(Course.class); 
 
    //Marshall Java object to XML 
    Marshaller marshaller = context.createMarshaller(); 
    //Set option to format generated XML 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 
true); StringWriter stringWriter = new StringWriter(); //Marshal Course object and write to the StringWriter marshaller.marshal(course, stringWriter); //Get String from the StringWriter String courseXml = stringWriter.getBuffer().toString(); stringWriter.close(); //Print course XML System.out.println(courseXml); //Now unmarshall courseXML to create Course object Unmarshaller unmarshaller = context.createUnmarshaller(); //Create StringReader from courseXml StringReader stringReader = new StringReader(courseXml); //Create StreamSource which will be used by JAXB unmarshaller StreamSource streamSource = new StreamSource(stringReader); Course unmarshalledCourse =
unmarshaller.unmarshal(streamSource, Course.class).getValue();
System.out.println("-----------------nUnmarshalled course name - " + unmarshalledCourse.getName()); stringReader.close(); } }

To marshal or unmarshal using JAXB, we first create JAXBContext, passing it a Java class that needs to be worked on. Then, we create the marshaller or unmarshaller, set the relevant properties, and perform the operation. The code is quite simple. We first marshal the Course instance to XML, and then use the same XML output to unmarshal it back to a Course instance. Right-click on the class and select Run As | Java Application. You should see the following output in the console:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<course id="1" xmlns:ns2="http://packt.jee.eclipse.jaxb.example"> 
    <ns2:name>Course-1</ns2:name> 
    <credits>5</credits> 
    <course_teacher> 
        <id>1</id> 
        <name>Teacher-1</name> 
    </course_teacher> 
</course> 
 
----------------- 
Unmarshalled course name - Course-1 

Let's now see how to marshal a Java object to JSON and back. JSON support in JAXB is not available out of the box in JDK. We will have to use an external library that supports JAXB APIs with JSON. One such library is EclipseLink MOXy (https://eclipse.org/eclipselink/#moxy). We will use this library to marshal an instance of Course to JSON.

Open pom.xml and add the dependency on EclipseLink:

  <dependencies> 
    <dependency> 
      <groupId>org.eclipse.persistence</groupId> 
      <artifactId>eclipselink</artifactId> 
      <version>2.6.1-RC1</version> 
    </dependency> 
  </dependencies> 

We also need to set the javax.xml.bind.context.factory property to make the JAXB implementation use EclipseLink's JAXBContextFactory. Create the jaxb.properties file in the same package as the classes whose instances are to be marshalled. In this case, create the file in the packt.jee.eclipse.jaxb.example package. Set the following property in this file:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

This is very important. If you do not set this property, then the example won't work. Next, open JAXBExample.java and add the following method:

  //Create JSON from Java object and then vice versa 
  public static void doJAXBJson() throws Exception { 
 
    Course course = new Course(1,"Course-1", 5); 
    course.setTeacher(new Teacher(1, "Teacher-1")); 
 
    JAXBContext context = JAXBContext.newInstance(Course.class); 
 
    //Marshal Java object to JSON 
    Marshaller marshaller = context.createMarshaller(); 
    //Set option to format generated JSON 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 
true); marshaller.setProperty(MarshallerProperties.MEDIA_TYPE,
"application/json"); marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT,
true); StringWriter stringWriter = new StringWriter(); //Marshal Course object and write to the StringWriter marshaller.marshal(course, stringWriter); //Get String from the StringWriter String courseJson = stringWriter.getBuffer().toString(); stringWriter.close(); //Print course JSON System.out.println(courseJson); //Now, unmarshall courseJson to create Course object Unmarshaller unmarshler = context.createUnmarshaller(); unmarshler.setProperty(MarshallerProperties.MEDIA_TYPE,
"application/json"); unmarshler.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT,
true); //Create StringReader from courseJson StringReader stringReader = new StringReader(courseJson); //Create StreamSource which will be used by JAXB unmarshaller StreamSource streamSource = new StreamSource(stringReader); Course unmarshalledCourse = unmarshler.unmarshal(streamSource,
Course.class).getValue();
System.out.println("-----------------nUnmarshalled course name - " + unmarshalledCourse.getName()); stringReader.close(); }

Much of the code is the same as in the doJAXBXml method. Specific changes are as follows:

  • We set the marshaller property for generating the JSON output (application/json)
  • We set another marshaller property to include the JSON root in the output
  • We set the corresponding properties on unmarshaller

Modify the main method to call doJAXBJson, instead of doJAXBXml. When you run the application, you should see the following output:

{ 
   "course" : { 
      "id" : 1, 
      "name" : "Course-1", 
      "credits" : 5, 
      "course_teacher" : { 
         "id" : 1, 
         "name" : "Teacher-1" 
      } 
   } 
} 
----------------- 
Unmarshalled course name - Course-1 

We have covered the basics of JAXB in this chapter. For a detailed tutorial on JAXB, refer to https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.133.180