JAXB: Marshalling and Unmarshalling CDATA block using EclipseLink MOXy

Project Description

  • In the example provided here, we saw how to marshal and unmarshal CDATA block using JAXB RI by creating custom adapter class.
  • In this JAXB example we will see how to marshal and unmarshal CDATA block using MOXy implementation which is available as part of Eclipselink project.
  • When using MOXy JAXB implementation there is no need to write custom adapter. Just an annotation (provided by MOXy) is sufficient to handle CDATA.

Environment Used:

  • JDK 6 (Java SE 6) or later.
  • Eclipse Indigo IDE for Java EE Developers.
  • EclipseLink 2.3.2 (Download EclipseLink from here and extract the zip file). We need this for MOXy which is an implementation of JAXB API.

New project in Eclipse

Create a new Java project in Eclipse IDE and name it as JAXBCDataMoxyImpl.

Add JAR file

  • You need to add eclipselink.jar file located in “eclipselink/jlib” in your project Build Path.
  • Right click on project -> Properties -> Java Build Path from left pane -> Libraries from right pane -> Add External JARs…

Create Bean class

Create a new Class “Book.java” in the package “com.theopentutorials.jaxb.to” and copy the following code.

package com.theopentutorials.jaxb.to;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlCDATA;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "book")
public class Book {

	private String name;
	private String author;
	private String publisher;
	private String isbn;

	@XmlCDATA
	private String description;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public String getIsbn() {
		return isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Override
	public String toString() {
		return "Book [name=" + name + ", author=" + author + ", publisher="
				+ publisher + ", isbn=" + isbn + ", description=" + description
				+ "]";
	}
}

This is a simple bean class containing JAXB annotations whose object is marshalled and unmarshalled. The ‘description’ property is annotated with @XmlCDATA which is provided by MOXy and vendor specific.

jaxb.properties file

To use MOXy as your JAXB implementation you need to add a jaxb.properties file in the bean package.
Create a new file “jaxb.properties” in the package “com.theopentutorials.jaxb.to” and copy the following entry.

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

Create JAXB Handler (Helper class)

Create a new Class “JAXBXMLHandler.java” in the package “com.theopentutorials.jaxb.xml” and copy the following code.

package com.theopentutorials.jaxb.xml;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import com.theopentutorials.jaxb.to.Book;

public class JAXBXMLHandler {

	public static Book unmarshal(File importFile) throws JAXBException {
		Book book = new Book();
		JAXBContext context;

		context = JAXBContext.newInstance(Book.class);
		Unmarshaller um = context.createUnmarshaller();
		book = (Book) um.unmarshal(importFile);
		return book;
	}

	public static void marshal(Book book, Class[] classes,
			Map<String, Map<String, StreamSource>> properties, File selectedFile)
			throws IOException, JAXBException {
		JAXBContext context;
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(selectedFile));
			context = JAXBContext.newInstance(classes, properties);
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			m.marshal(book, writer);
		} finally {
			try {
				writer.close();
			} catch (IOException io) {/* ignore */
			}
		}
	}
}
  • This is a helper class which has methods to perform marshalling and unmarshalling. These methods are called from client code (in this case, main() method).
  • By default, the marshaller implementation of the JAXB RI tries to escape characters.
  • We use an overloaded JAXBContext.newInstance(Class) to configure ‘properties’ for this instantiation of JAXBContext. The interpretation of properties is implementation specific.

MOXy binding file

MOXy JAXB implementation allows you to enable a element to use CDATA. You could use MOXy’s binding file to indicate that the book’s ‘description’ property should use CDATA.
Create a XML file in your project and name it as “oxm.xml” and copy the following code.

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
   <java-types>
      <java-type name="com.theopentutorials.jaxb.to.Book">
         <java-attributes>
            <xml-element java-attribute="description" cdata="true"/>
         </java-attributes>
      </java-type>
   </java-types>
</xml-bindings>

Create Java Application client (main())

Create a new Class “JAXBCDataDemo.java” in the package “com.theopentutorials.jaxb.main” and copy the following code.

package com.theopentutorials.jaxb.main;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBException;
import javax.xml.transform.stream.StreamSource;
import com.theopentutorials.jaxb.to.Book;
import com.theopentutorials.jaxb.xml.JAXBXMLHandler;

public class JAXBCDataDemo {
	public static void main(String[] args) {

		Book book = new Book();
		book.setAuthor("Kathy Sierra");
		book.setName("SCJP");
		book.setPublisher("Tata McGraw Hill");
		book.setIsbn("856-545456736");

		String desc = "<p>With hundreds of practice questions and hands-on exercises, "
				+ "<b>SCJP Sun Certified Programmer for Java 6 Study Guide</b>" +
				"covers what you need to know"
				+ "--and shows you how to prepare--" +
				"for this challenging exam. </p>";
		book.setDescription(desc);

		Map<String, StreamSource> oxm = new HashMap<String, StreamSource>(1);
		oxm.put("com.theopentutorials.jaxb.to", new StreamSource("oxm.xml"));

		Map<String, Map<String, StreamSource>> properties =
				new HashMap<String, Map<String, StreamSource>>();
		properties.put("eclipselink-oxm-xml", oxm);

		Class[] classes = { Book.class };

		try {
			//Marshalling: Writing Java object to XML file
			JAXBXMLHandler.marshal(book, classes, properties, new File("book.xml"));

			//Unmarshalling: Converting XML content to Java objects
			Book book2 = JAXBXMLHandler.unmarshal(new File("book.xml"));
			System.out.println("Unmarshal: " + book2);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
}
  • This class creates book object with ‘description’ property containing HTML tags and calls marshal method from JAXBXMLHandler helper class passing book object and the file to write the object.
  • We call unmarshal method passing the marshalled file name which returns a book object.
  • Finally, printing the book object (which calls toString() from Book class).

Output

Run the JAXBCDataDemo.java.

Book [name=SCJP, author=Kathy Sierra, publisher=Tata McGraw Hill, isbn=856-545456736, description=
<p>With hundreds of practice questions and hands-on exercises, <b>SCJP Sun Certified Programmer for Java 6 Study Guide</b> covers what you need to know–and shows you how to prepare–for this challenging exam. </p>]

Refresh your project in Project Explorer (press F5 on your project) to see the generated XML file.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <name>SCJP</name>
    <author>Kathy Sierra</author>
    <publisher>Tata McGraw Hill</publisher>
    <isbn>856-545456736</isbn>
    <description><![CDATA[<p>With hundreds of practice questions
        and hands-on exercises, <b>SCJP Sun Certified Programmer
        for Java 6 Study Guide</b> covers what you need to know--
        and shows you how to prepare --for this challenging exam. </p>]]>
    </description>
</book>

Folder Structure

The complete folder structure of this example is shown below.

Leave a Comment