JAXB: Marshalling and Unmarshalling CDATA block using EclipseLink MOXy

Language/JAVA 2013. 9. 3. 13:46


eclipselink.jar

JAXB: Marshalling and Unmarshalling CDATA block using EclipseLink MOXy

11 November 2012 By Nithya Vasudevan 1,575 views 9 Comments
Rating: 0.0/5 (0 votes cast)

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.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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 andunmarshalled. 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.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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.

01
02
03
04
05
06
07
08
09
10
<?xml version="1.0" encoding="UTF-8"?>
   <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.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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.

01
02
03
04
05
06
07
08
09
10
11
12
<?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.


: