Convert XML to JSON Using Jackson

1. Overview

In this tutorial, we’ll see how to convert an XML message to JSON using Jackson.

For readers new to Jackson, consider getting familiar with the basics first.

2. An Introduction to Jackson

We can think about parsing JSON in three different ways with Jackson:

  • The first and most common is data binding with ObjectMapper
  • The second is mapping to a tree data structure with TreeTraversingParser and JsonNode
  • And the third is streaming the tree data structure by token, using JsonParser and JsonGenerator

Now, Jackson also supports the first two for XML data. As such, let’s see how Jackson can help us do the conversion from one format to the other.

3. Dependencies

First, we need to add the jackson-databind dependency to our pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

This library is going to allow us to use the data binding API.

The second is jackson-dataformat-xml which adds Jackson’s XML support:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.1</version>
</dependency>

4. Data Binding

Data binding, simply put, is when we want to map serialized data directly to a Java object.

To explore this, let’s define our XML with Flower and Color properties:

<Flower>
    <name>Poppy</name>
    <color>RED</color>
    <petals>9</petals>
</Flower>

This is similar to this Java notation:

public class Flower {
    private String name;
    private Color color;
    private Integer petals;
    // getters and setters
}

public enum Color { PINK, BLUE, YELLOW, RED; }

Our first step will be to parse the XML into a Flower instance. To do that, let’s create an instance of XmlMapper, Jackson’s XML equivalent for ObjectMapper and use its readValue method:

XmlMapper xmlMapper = new XmlMapper();
Flower poppy = xmlMapper.readValue(xml, Flower.class);

Once we have our Flower instance, we’ll want to write it out as JSON using the familiar ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(poppy);

And, as a result, we get our JSON equivalent:

{
    "name":"Poppy",
    "color":"RED",
    "petals":9
}

5. Tree Traversal

At times, looking directly at the tree structure can offer more flexibility, like in the case that we don’t want to maintain an intermediary class or we only want to convert a portion of the structure.

Though, as we’ll see, it comes with some tradeoffs.

The first step is similar to our first step when we use data binding. This time, though, we’ll use the readTree method:

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());

Having done this, we’ll have a JsonNode which has 3 children, as we expected: name, color, and petals.

Then, we can again use ObjectMapper, just sending our JsonNode instead:

ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);

Now, the outcome is slightly different compared to our last example:

{
    "name":"Poppy",
    "color":"RED",
    "petals":"9"
}

Upon careful inspection, we can see that the petals attribute is serialized into a string instead of a number! This is because readTree doesn’t infer the datatype without an explicit definition.

5.1. Limitations

And, there are certain limitations with Jackson’s XML tree traversal support:

  • Jackson cannot differentiate between an Object and an Array. Since XML lacks native structures to distinguish an object from a list of objects, Jackson will simply collate repeated elements into a single value.
  • And, since Jackson wants to map each XML element to a JSON node, it doesn’t support mixed content.

For these reasons, the official Jackson docs recommend against using Tree models to parse XML.

6. Memory Constraints

Now, both of these have the notable downside that the entire XML needs to be in memory at once in order to perform the conversion. Until Jackson supports streaming the tree structure as tokens, we’ll be stuck with this constraint or we’ll need to take a look at rolling our own with something like XMLStreamReader.

7. Conclusion

In this tutorial, we briefly learned different ways in which Jackson can read XML data and write it to JSON. Also, we took a quick look at the limitations of each supported approach.

As usual, the full source code that accompanies the tutorial is available over on GitHub.

Related posts:

Spring REST API with Protocol Buffers
Comparing Two HashMaps in Java
Java Program to Implement Gaussian Elimination Algorithm
Spring Security Logout
The Dining Philosophers Problem in Java
Guide to java.util.Formatter
Java Program to Generate All Subsets of a Given Set in the Gray Code Order
Logout in an OAuth Secured Application
Hướng dẫn Java Design Pattern – Facade
Java Program to Implement Traveling Salesman Problem using Nearest neighbour Algorithm
Java Program to Use rand and srand Functions
Java Program to Solve TSP Using Minimum Spanning Trees
Introduction to Project Reactor Bus
ThreadPoolTaskExecutor corePoolSize vs. maxPoolSize
What is Thread-Safety and How to Achieve it?
How to Delay Code Execution in Java
Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
Java Program to Implement Pagoda
Spring MVC + Thymeleaf 3.0: New Features
Java 8 Stream findFirst() vs. findAny()
Java Program to Find MST (Minimum Spanning Tree) using Kruskal’s Algorithm
Lớp Arrarys trong Java (Arrays Utility Class)
Mix plain text and HTML content in a mail
List Interface trong Java
Java Program to Implement Find all Back Edges in a Graph
Java Program to Implement Sorted Doubly Linked List
Returning Image/Media Data with Spring MVC
Java Program to Implement Branch and Bound Method to Perform a Combinatorial Search
Java – Combine Multiple Collections
Java Program to Implement Gauss Seidel Method
Guide to CountDownLatch in Java
Java Program to Print the Kind of Rotation the AVL Tree is Undergoing