Using JAXB For XML With Java - DZone Java
Using JAXB For XML With Java - DZone Java
Download DZone’s 2019 Kubernetes Trend Report to see the future impact Kubernetes will have.
Download Report
Java Architecture for XML Binding (JAXB) is a library that helps bind XML schemas and Java representations.
JAXB provides you with a mechanism to marshal Java objects into XML and the other way around –
unmarshal XML into Java objects.
XML is an industry standard for de ining the contents of your message. XML, along with Java, are
complementary technologies to exchange data across the Internet. When you work with XML, you need a way
to take an XML ile, then convert it into some sort of data structure, which your program can manipulate. You
also need to serialize the state of your Java objects into XML. JAXB is one library that performs such
marshalling and unmarshalling operations.
In this post, I will discuss on how to marshal Java objects into XML and the other way around using JAXB.
Our intent is to marshal the Product object, along with its composed User object into XML by using JAXB.
User.java:
1 package guru.springframework.blog.domain;
2
3 public class User {
7
8 public User() {
9 }
10
11 public User(Long id, String name, String email) {
12 this.id = id;
13 this.name = name;
14 this.email = email;
https://dzone.com/articles/using-jaxb-for-xml-with-java 1/20
9/18/2019 Using JAXB for XML With Java - DZone Java
15 }
16
17 public Long getId() {
18 return id;
19 }
20
21 public User setId(Long id) {
22 this.id = id;
23 return this;
24 }
25
26 public String getName() {
27 return name;
28 }
29
30 public User setName(String name) {
31 this.name = name;
32 return this;
33 }
34
35 public String getEmail() {
36 return email;
37 }
38
39 public User setEmail(String email) {
40 this.email = email;
41 return this;
42 }
43
44 @Override
47 sb.append("id=").append(id);
48 sb.append(", name='").append(name).append('\'');
49 sb.append(", email='").append(email).append('\'');
50 sb.append('}');
51 return sb.toString();
52 }
53 }
User is a simple POJO with the id, name, and email ields, along with their corresponding getter and setter
methods.
Next, we will create the Product POJO. While creating this POJO, we will use annotations introduced in JAXB 2.0
to control how our Product object is marshalled to XML.
Note: As of JDK 1.6, JAXB is bundled with the JDK. Therefore, you don’t need to add any dependency for it.
Product.java
1 package guru.springframework.blog.domain;
2
3 import javax.xml.bind.annotation.*;
4 import java.math.BigDecimal;
5
6 @XmlRootElement(name = "product")
7 //@XmlAccessorType(XmlAccessType.FIELD)
9 @XmlAttribute(name = "id")
11 @XmlElement(name = "description")
13 @XmlElement(name = "imageUrl")
15 @XmlElement(name = "price")
17 @XmlElement(name = "createdBy")
19 public Product(){}
22 this.productId = productId;
23 this.description = description;
24 this.imageUrl = imageUrl;
25 this.price = price;
26 this.createdBy = createdBy;
27 }
28
29 @Override
31 return "Product{" +
37 '}';
38 }
39 }
@XmlRootElement: This annotation is used at the top level class to indicate the root element in the XML
document. The name attribute in the annotation is optional. If not speci ied, the class name is used as
the root XML element in the document.
l b h
https://dzone.com/articles/using-jaxb-for-xml-with-java d d h b f h l 3/20
9/18/2019 Using JAXB for XML With Java - DZone Java
@XmlAttribute: This annotation is used to indicate the attribute of the root element.
@XmlElement: This annotation is used on the properties of the class that will be the sub-elements of the
root element.
The Product POJO is now ready to be marshalled into XML. To do so, let us write a JUnit test class. If you are
new to JUnit, I suggest going through my Unit Testing with JUnit series.
ProductToXmlTest.java:
1 package guru.springframework.blog.marshal;
2
3 import guru.springframework.blog.domain.Product;
4 import guru.springframework.blog.domain.User;
5 import org.junit.After;
6 import org.junit.Before;
7 import org.junit.Test;
8 import javax.xml.bind.JAXBContext;
9 import javax.xml.bind.JAXBException;
10 import javax.xml.bind.Marshaller;
11 import java.io.File;
12 import java.io.FileNotFoundException;
13 import java.math.BigDecimal;
14
15 public class ProductToXmlTest {
17
18 @Before
20 long l = 10;
25
26 @After
28 product = null;
29 }
30
31 @Test
35 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
37 marshaller.marshal(product, System.out);
38 }
https://dzone.com/articles/using-jaxb-for-xml-with-java 4/20
9/18/2019 Using JAXB for XML With Java - DZone Java
39 }
In this code:
Line 19 – Line 24: Instantiates and initializes a User and a Product object in the setup() method marked
as @Before.
Line 33: The JAXBContext.newInstance() method obtains a JAXBContext for the Product class that you
want to marshal. JAXBContext provides the entry point for the JAXB API.
Line 34: Creates a Marshaller through a call to the createMarshaller() method of JAXBContext. In JAXB,
the Marshaller class governs the process of marshalling Java objects into XML data through its various
marshalling methods.
Line 35: Con igures the Marshaller. The true value of the JAXB_FORMATTED_OUTPUT property instructs
the Marshaller to generate the XML with proper indentation.
Line 36: Calls the marshal() method on the Marshaller with the initialized Product object and the ile to
write the XML.
Line 37: Marshals the object to the “standard” output stream.
The JUnit test class to unmarshal the generated product.xml back to the Product and User objects is this:
XmlToProductTest.java:
1 package guru.springframework.blog.unmarshal;
2
3 import guru.springframework.blog.domain.Product;
4 import guru.springframework.blog.domain.User;
5 import org.junit.After;
6 import org.junit.Before;
7 import org.junit.Test;
8
9 import javax.xml.bind.JAXBContext;
10 import javax.xml.bind.JAXBException;
11 import javax.xml.bind.Marshaller;
12 import javax.xml.bind.Unmarshaller;
13 import java.io.File;
https://dzone.com/articles/using-jaxb-for-xml-with-java 5/20
9/18/2019 Using JAXB for XML With Java - DZone Java
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.math.BigDecimal;
16
17 public class XmlToProductTest {
19 @Test
25 System.out.println(product);
26 }
27 }
In this XmlToProductTest class, a JAXBContext initialized with Product is used. The createUnmarsheller()
method returns an Unmarshaller. A JAXB Unmarshaller governs the process of unmarhshalling XML data into
a Java object tree. Finally, the unmarshal() method unmarshals the File object for product.xml into the
Product POJO.
Handling Collections
Often you will need to marshal Java collection objects, such as List, Set, and Map to XML, and also unmarshal
XML back to collection objects.
Consider our current application, where we now need to work with a list of products. To model the new
requirement, let us create a Products class.
Products.java:
1 package guru.springframework.blog.domain;
2
3 import javax.xml.bind.annotation.XmlElement;
4 import javax.xml.bind.annotation.XmlRootElement;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 @XmlRootElement(name = "products")
10 List<Product> products;
12 return products;
13 }
14
15 @XmlElement(name = "product")
17 this.products = products;
18 }
19
20 public void add(Product product) {
21 if (this.products == null) {
23 }
24 this.products.add(product);
25
26 }
27 }
In this Products class, the @XmlRootElement annotation speci ies the root element of the XML as products.
This class has a single List property with getter and setter methods. The add() method of this class accepts a
Product object and adds it to the List.
ProductToXmlListTest.java:
1 package guru.springframework.blog.marshal;
2
3 import guru.springframework.blog.domain.Product;
4 import guru.springframework.blog.domain.Products;
5 import guru.springframework.blog.domain.User;
6 import org.junit.After;
7 import org.junit.Before;
8 import org.junit.Test;
9
10 import javax.xml.bind.JAXBContext;
11 import javax.xml.bind.JAXBException;
12 import javax.xml.bind.Marshaller;
13 import javax.xml.bind.Unmarshaller;
14 import java.io.File;
15 import java.io.FileNotFoundException;
16 import java.math.BigDecimal;
17
18 public class ProductToXmlListTest {
21
22 @Before
24 long l = 10;
https://dzone.com/articles/using-jaxb-for-xml-with-java 7/20
9/18/2019 Using JAXB for XML With Java - DZone Java
24
25 Long longId = new Long(l);
30
31 @After
33 product = null;
34 }
35
36 @Test
39 products.add(product);
40 products.add(product1);
41
42 JAXBContext jaxbContext = JAXBContext.newInstance(Products.class);
44 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
46 marshaller.marshal(products, System.out);
47 }
48 }
Summary
In this post, I have covered the introductory concepts of JAXB. I have previously written a post on how to use
an XML Schema and JAXB to generate Java classes for RESTful web services here.
JAXB also comes with a JAXB Binding compiler tool named schemagen. You can use schemagen to generate an
XSD schema from Java classes.
The source code for this post is available on GitHub. You can download it here.
https://dzone.com/articles/using-jaxb-for-xml-with-java 8/20
9/18/2019 Using JAXB for XML With Java - DZone Java
Published at DZone with permission of John Thompson , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
In this post, we will look at some refactoring techniques using types. Types can be used to represent the
domain in a ine-grained, well-de ined way. Additionally, types can be used to incorporate business rules in a
manner that ensures code correctness. This enables us to write simple and elegant unit tests to ensure code
correctness
https://dzone.com/articles/using-jaxb-for-xml-with-java 9/20
9/18/2019 Using JAXB for XML With Java - DZone Java
correctness.
8 }
The code above is a classic example of a code smell called primitive obsession.
All the above parameters are represented using numbers. However, are they just numbers?
Is UnitPrice interchangeable with ListPrice or Tax ?
In domain-driven design, these are indeed distinct things and not just numbers. Ideally, we would like to have
speci ic types to represent these concepts.
The irst level of refactoring is to create simple wrapper types for these classes:
2 private ListPrice() {
3 }
6 setListPrice(listPrice);
7 }
10 if (listPrice < 0) {
12 }
13 this.listPrice = listPrice;
14 }
15 }
2 private UnitPrice() {
3 }
https://dzone.com/articles/using-jaxb-for-xml-with-java 10/20
9/18/2019 Using JAXB for XML With Java - DZone Java
6 setUnitPrice(unitPrice);
7 }
10 if (unitPrice < 0) {
12 }
13 this.unitPrice = unitPrice;
14 }
15 }
This serves as a good starting point. We now have conceptual constructs for these. Any business rules
required for a construct can now be wired within these constructs rather than being implemented in the
container OrderLine class.
However, if we observe that there is duplicate code to check that the listPrice and unitPrice are not be null
or non-negative, this check would most probably be applied to quantity, tax, and charge as well.
Hence, it makes sense to create a Type , which represents a non-negative number concept.
4 this.setValue(value);
5 }
10 }
11 this.value = value;
12 }
13 }
Now, we can safely refactor the UnitPrice and ListPrice classes to use this new construct of a non-negative
double.
2 private UnitPrice() {
3 }
4 private
5 @Getter
6 NonNegativeDouble unitPrice;
8 setUnitPrice(unitPrice);
9 }
https://dzone.com/articles/using-jaxb-for-xml-with-java 11/20
9/18/2019 Using JAXB for XML With Java - DZone Java
11 this.unitPrice = unitPrice;
12 }
13 }
A simple test to validate the non-negative constraints for UnitPrice , use the following code:
1 @Unroll
4 given:
5 def unitPrice
6 when:
8 try {
11 isExceptionThrown = true
12 }
13 then:
15 where:
21 'Invalid' | 0 | false
26 }
27 }
Although this showcases a simple use case for refactoring using types, it applies to a lot of constructs which
are modeled as primitive types, like Email, Names, Currency, Ranges, and Date and Time.
https://dzone.com/articles/using-jaxb-for-xml-with-java 12/20
9/18/2019 Using JAXB for XML With Java - DZone Java
4
5 public CustomerContact(EmailContactInfo emailContactInfo,
6 PostalContactInfo postalContactInfo){
7 setEmailContactInfo(emailContactInfo);
8 setPostalContactInfo(postalContactInfo);
9 }
11 Objects.requireNonNull(emailContactInfo,"Email Contact
13 this.emailContactInfo = emailContactInfo;
14 }
16 Objects.requireNonNull(postalContactInfo,"Postal Contact
18 this.postalContactInfo = postalContactInfo;
19 }
20
21 }
Let's assume a simple business rule, which states: "A customer contact must have either email contact
information or postal contact information."
This implies that there should be at least one of either the EmailContactInfo or the CustomerContactInfo . Both
can also be present. However, our current implementation requires both to be present.
In order to apply the business rule, a irst attempt might look like this:
4
5 public CustomerContact(PersonName name, Optional<EmailContactInfo> emailContactInfo,
6 Optional<PostalContactInfo> postalContactInfo){
7 setEmailContactInfo(emailContactInfo);
8 setPostalContactInfo(postalContactInfo);
9 }
11 this.emailContactInfo = emailContactInfo;
12 }
14 this.postalContactInfo = postalContactInfo;
15 }
16
17 }
https://dzone.com/articles/using-jaxb-for-xml-with-java 13/20
9/18/2019 Using JAXB for XML With Java - DZone Java
Now, we have gone too far the other way. The rule requires that the CustomerContact should have at least one
of email or postal contact. However, with the current implementation, it is possible for the CustomerContact to
not have any of them.
In a functional language, such conditions can be designed using sum types. However, in languages like Java,
there is no irst-class support for these constructs. There are libraries like JavaSealedUnions, which provide
support for Sum and Union types in java.
1
2 public abstract class CustomerContact implements Union2<EmailContact, PostalContact> {
3
4 public abstract boolean valid();
5
6 public static CustomerContact email(String emailAddress) {
8 }
9
10 public static CustomerContact postal(String postalAddress) {
12 }
13 }
14
15 class EmailContact extends CustomerContact {
16
17 private final String emailAddress;
18
19
20 EmailContact(String emailAddress) {
21 this.emailAddress = emailAddress;
22 }
23
24 public boolean valid() {
26 }
27
public void continued(Consumer<EmailContact> continuationLeft, Consumer<PostalContact> con
28
29 continuationLeft.call(value);
30 }
31
public <T> T join(Function<EmailContact, T> mapLeft, Function<PostalContact, T> mapRight)
32
33 return mapLeft.call(value);
34 }
35 }
https://dzone.com/articles/using-jaxb-for-xml-with-java 14/20
9/18/2019 Using JAXB for XML With Java - DZone Java
36
37 class PostalContact extends CustomerContact {
38
39 private final String address;
40
41
42 PostalContact(String address) {
43 this.address = address;
44
45 }
46
47 public boolean valid() {
49 }
50
public void continued(Consumer<EmailContact> continuationLeft, Consumer<PostalContact> con
51
52 continuationRight.call(value);
53 }
54
public <T> T join(Function<EmailContact, T> mapLeft, Function<PostalContact, T> mapRight)
55
56 return mapRight.call(value);
57 }
58 }
59
60
61 // Example
62
63 CustomerContact customerContact = getCustomerContact();
64 if (customerContact.valid()) {
customerContact.continued(customerContactService::byEmail(), customerContactService::byPos
65
66 }
This post shows some of the ways we were thinking in terms of how Types can help in having a cleaner
design. Types also help to avoid ambiguity around business rules. The approaches shown above can also be
used in other scenarios to either capture allowed states or success and failure cases.
Further Reading
What Is Refactoring?
https://dzone.com/articles/using-jaxb-for-xml-with-java 15/20
9/18/2019 Using JAXB for XML With Java - DZone Java
Topics: REFACTORING
Published at DZone with permission of Maneesh Chaturvedi . See the original article here.
Opinions expressed by DZone contributors are their own.
Using the Stream API and the map method, we can transform elements in a stream to another object. Instead
of using the map method, we can also write a custom Collector and transform the elements when we use the
collect method as a terminal operation of the stream.
https://dzone.com/articles/using-jaxb-for-xml-with-java 16/20
9/18/2019 Using JAXB for XML With Java - DZone Java
First, we have an example where we transform String value using the map method:
1 package mrhaki;
2
3 import java.util.List;
4 import java.util.stream.Collectors;
5
6 public class CollectorString {
9
10 final List<String> upper =
11 items.stream()
12 .map(String::toUpperCase)
13 .collect(Collectors.toUnmodifiableList());
14
15 assert upper.equals(List.of("JFALL", "JAVAZONE", "CODEONE"));
16 }
17 }
In our next example, we don't use the map method, but we write a custom Collector using the Collector.of
method. As the irst argument, we must provide the data structure we want to add elements too, the so-called
supplier, which is an ArrayList .
The second argument is an accumulator where we add each element from the stream to the list and
transform the value. The third argument is the combiner, and here, we combine multiple List instances to
one List instance. The last argument is a inisher, and we make an immutable List to be returned.
1 package mrhaki;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.stream.Collector;
7
8 public class CollectorString1 {
11
12 final List<String> upper =
13 items.stream()
16 .collect(upperCollect());
17
https://dzone.com/articles/using-jaxb-for-xml-with-java 17/20
9/18/2019 Using JAXB for XML With Java - DZone Java
19 }
20
21 private static Collector<String, ?, List<String>> upperCollect() {
22 return Collector.of(
26
27 // Next we add each String value to the list
30
31 // Next we get two lists we need to combine,
35
36 // Finally (and optionally) we turn the
39 }
40 }
Further Reading
A Guide to Streams: In-Depth Tutorial With Examples
Topics: JAVA, STREAMS, COLLECTOR, JAVA STREAM API, JAVA API, MAP, JAVA STREAM
https://dzone.com/articles/using-jaxb-for-xml-with-java 18/20
9/18/2019 Using JAXB for XML With Java - DZone Java
Published at DZone with permission of Hubert Klein Ikkink , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Hi, Spring fans! Welcome to another sunny installment of This Week in Spring! Can you believe we're now
staring down Q4 2019? How time lies!
As I write this, I'm sitting in the Radisson Blu hotel in Oslo, Norway, for the epic JavaZone show. I've got tons of
wonderful memories at this hotel, often enjoyed with my friends on the Spring team over the course of many,
many years. I love this show and am so glad to be back for the irst time since 2015!
I landed today, recorded a few episodes of Spring Tips (new season starting soon!), took an ill-timed nap, and
now here we are! We've got a ton to cover, so let's get to it!
Topics: JAVA, NEWS, SPRING, SPRING FRAMEWORK, SPRING BOOT, RELEASES, KUBERNETES, SPRING SECURITY,
SPRING CLOUD, AZURE
Published at DZone with permission of Joshua Long , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
https://dzone.com/articles/using-jaxb-for-xml-with-java 20/20