Jackson and JSON in Java, finally learn with a coding-first approach:
>> Download the eBookMocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.
Get started with mocking and improve your application tests using our Mockito guide:
Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.
Get started with understanding multi-threaded applications with our Java Concurrency guide:
Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:
Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.
But these can also be overused and fall into some common pitfalls.
To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:
Get started with Spring and Spring Boot, through the Learn Spring course:
>> LEARN SPRINGExplore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:
Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.
I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.
You can explore the course here:
Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.
Get started with Spring Data JPA through the guided reference course:
Refactor Java code safely β and automatically β with OpenRewrite.
Refactoring big codebases by hand is slow, risky, and easy to put off. Thatβs where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.
Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions β one for newcomers and one for experienced users. Youβll see how recipes work, how to apply them across projects, and how to modernize code with confidence.
Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.
1. Overview
In this tutorial, weβll learn how to serialize Java objects to XML data using Jackson 2.x, and deserialize them back to a POJO.
Weβll focus on the basic operation that doesnβt require a lot of complexity or customization.
2. XmlMapper Object
XmlMapper is the main class from Jackson 2.x that helps us in serialization, so weβll need to create an instance of it:
XmlMapper mapper = new XmlMapper();
This mapper is available in the jackson-dataformat-xml jar, so we have to add it as a dependency to our pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.1</version>
</dependency>
Please check the latest version of the jackson-dataformat-xml dependency in the Maven repository.
3. Serialize Java to XML
XmlMapper is a subclass of ObjectMapper, which is used in JSON serialization; however, it adds some XML specific tweaks to the parent class.
Letβs look at how to use it to do the actual serialization. Letβs create a Java class first:
class SimpleBean {
private int x = 1;
private int y = 2;
//standard setters and getters
}
3.1. Serialize to the XML String
We can serialize our Java object into the XML String:
@Test
public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException {
XmlMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValueAsString(new SimpleBean());
assertNotNull(xml);
}
As a result, weβll get:
<SimpleBean>
<x>1</x>
<y>2</y>
</SimpleBean>
3.2. Serialize to the XML File
We can also serialize our Java object to the XML file:
@Test
public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.writeValue(new File("simple_bean.xml"), new SimpleBean());
File file = new File("simple_bean.xml");
assertNotNull(file);
}
And below we can see the content of the resulting file named simple_bean.xml:
<SimpleBean>
<x>1</x>
<y>2</y>
</SimpleBean>
4. Deserialize XML to Java
In this section, weβll look at how to obtain Java objects from XML.
4.1. Deserialize From the XML String
As with serialization, we can also deserialize an XML String back to a Java object:
@Test
public void whenJavaGotFromXmlStr_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
SimpleBean value
= xmlMapper.readValue("<SimpleBean><x>1</x><y>2</y></SimpleBean>", SimpleBean.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
4.2. Deserialize From the XML File
Likewise, if we have an XML file, we can convert it back to a Java object.
@Test
public void whenJavaGotFromXmlFile_thenCorrect() throws IOException {
File file = new File("simple_bean.xml");
XmlMapper xmlMapper = new XmlMapper();
SimpleBean value = xmlMapper.readValue(file, SimpleBean.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
5. Handling Capitalised Elements
In this section, weβll discuss how to handle scenarios where we either have XML with capitalized elements to deserialize, or we need to serialize Java objects to XML with one or more elements capitalized.
5.1. Deserialize From the XML String
Letβs say we have an XML with one field capitalized:
<SimpleBeanForCapitalizedFields>
<X>1</X>
<y>2</y>
</SimpleBeanForCapitalizedFields>
In order to correctly handle capitalized elements, we need to annotate the βxβ field with the @JsonProperty annotation:
class SimpleBeanForCapitalizedFields {
@JsonProperty("X")
private int x = 1;
private int y = 2;
// standard getters, setters
}
We can now correctly deserialize an XML String back to a Java object:
@Test
public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
SimpleBeanForCapitalizedFields value
= xmlMapper.readValue(
"<SimpleBeanForCapitalizedFields><X>1</X><y>2</y></SimpleBeanForCapitalizedFields>",
SimpleBeanForCapitalizedFields.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}
5.2. Serialize to the XML String
By annotating the required fields with @JsonProperty, we can correctly serialize a Java object into an XML String with one or more capitalized elements:
@Test
public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect()
throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"),
new SimpleBeanForCapitalizedFields());
File file = new File("target/simple_bean_capitalized.xml");
assertNotNull(file);
}
6. Serialize List to XML
The XmlMapper is able to serialize an entire Java bean into a document. To convert a Java object to XML, weβll take a simple example with a nested object and arrays.
Our intent is to serialize a Person object, along with its composed Address object, into XML.
Our final XML will look something like:
<Person>
<firstName>Rohan</firstName>
<lastName>Daye</lastName>
<phoneNumbers>
<phoneNumbers>9911034731</phoneNumbers>
<phoneNumbers>9911033478</phoneNumbers>
</phoneNumbers>
<address>
<streetName>Name1</streetName>
<city>City1</city>
</address>
<address>
<streetName>Name2</streetName>
<city>City2</city>
</address>
</Person>
Notice that our phone numbers are encapsulated in a phoneNumbers wrapper, while our address isnβt.
We can express this nuance via the @JacksonXMLElementWrapper annotation in our Person class:
public final class Person {
private String firstName;
private String lastName;
private List<String> phoneNumbers = new ArrayList<>();
@JacksonXmlElementWrapper(useWrapping = false)
private List<Address> address = new ArrayList<>();
//standard setters and getters
}
In fact, we can change the wrapping element name with @JacksonXmlElementWrapper(localName = βphoneNumbersβ). Or, if we donβt want to wrap our elements, we can disable the mapping with @JacksonXmlElementWrapper(useWrapping = false).
Then weβll define our Address type:
public class Address {
String streetName;
String city;
//standard setters and getters
}
Jackson takes care of the rest for us. Like before, we can simply call writeValue again:
private static final String XML = "<Person>...</Person>";
@Test
public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
Person person = testPerson(); // test data
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
xmlMapper.writeValue(byteArrayOutputStream, person);
assertEquals(XML, byteArrayOutputStream.toString());
}
7. Deserialize XML to List
Jackson can read XML that contains lists of objects as well.
If we take our same XML as before, the readValue method does just fine:
@Test
public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
Person value = xmlMapper.readValue(XML, Person.class);
assertEquals("City1", value.getAddress().get(0).getCity());
assertEquals("City2", value.getAddress().get(1).getCity());
}
8. Conclusion
This brief article illustrated how to serialize a simple POJO to XML, and obtain a POJO from basic XML data.
We also explored how to serialize and deserialize complex beans that contain collections.
