How to transform data from XML to JSON with Camel

This article discusses how to transform data in a Camel route from XML to JSON using Jackson data format XML library. To test our Camel Route, we will include it in a Spring Boot application which receives as input an XML in its REST Controller.

Marshalling and Unmarshalling with Jackson

The com.fasterxml.jackson.dataformat:jackson-dataformat-xml library is a Jackson data format module that provides support for reading and writing XML data using Jackson. It is used to convert between XML and JSON formats.

Firstly, include the jackson-dataformat-xml library in your pom.xml along with Camel Spring Boot starter and Camel Jackson Starter:

<dependency>
      <groupId>org.apache.camel.springboot</groupId>
      <artifactId>camel-spring-boot-starter</artifactId>
 </dependency>

<dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
 
<dependency>
      <groupId>org.apache.camel.springboot</groupId>
      <artifactId>camel-jacksonxml-starter</artifactId>
</dependency>

Also, as you can see, to avoid setting versions for your starters, we recommend including the Spring Boot and Apache Camel Spring Boot pom files in your dependencies:

  <dependencyManagement>
    <dependencies>
      <!-- Spring Boot BOM -->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring.boot-version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!-- Camel BOM -->
      <dependency>
        <groupId>org.apache.camel.springboot</groupId>
        <artifactId>camel-spring-boot-dependencies</artifactId>
        <version>3.7.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

Coding the Camel Route

Next step, is to code an example Camel Route.

@Component
public class XmlToJsonRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        JacksonXMLDataFormat jacksonDataFormat = new JacksonXMLDataFormat();
        jacksonDataFormat.setPrettyPrint(true);
        jacksonDataFormat.enableFeature(SerializationFeature.WRAP_ROOT_VALUE);
        
         from("direct:xmlIn").log( "POJO Body ${body}").marshal(jacksonDataFormat)
         .log("XML Marshalled Body: ${body}").unmarshal(jacksonDataFormat).
                    log("Unmarshalled JSON Body: ${body}").
                       to("seda:output");
        
    }
}

This class extends the RouteBuilder class, which is a base class for creating Camel routes. The configure method is where we define the route.

We first create a new instance of JacksonXMLDataFormat, which is a data format for marshalling and unmarshalling XML data using the Jackson library. We set the prettyPrint property to true, which formats the JSON output with line breaks and indentation. We also enable the WRAP_ROOT_VALUE feature, which wraps the root element in an outer JSON object.

The route starts with a from method, which specifies the input endpoint for the route. In this case, we use the direct:xmlIn endpoint, which allows us to send XML data directly to the route. We then use the log method to log the input data.

Next, we use the marshal method to marshal the input XML data to JSON using the JacksonXMLDataFormat instance we created earlier. We use the log method again to log the marshalled JSON data.

We then use the unmarshal method to unmarshal the JSON data back to XML using the same JacksonXMLDataFormat instance. We use the log method one more time to redirect the output to a seda channel.

Coding a Spring Boot controller

Next, to feed some data in our direct component, we will add a Spring Boot REST Controller that takes consumes XML from one of its endpoints. To learn more about Spring Boot Controllers and XML check this article: Managing XML with Spring Boot Controllers .

Here is our Spring Boot Controller:

@RestController
public class MyController {
    @Autowired
    private ProducerTemplate producerTemplate;
    @Autowired
    ConsumerTemplate consumerTemplate;

    @RequestMapping(path = "/xml", 
    method = RequestMethod.POST, produces = MediaType.APPLICATION_XML_VALUE,
    consumes = MediaType.APPLICATION_XML_VALUE)
 
    public  String xmlToJson(@RequestBody Customer c) {
        
        System.out.println("Received "+c);
        producerTemplate.sendBody("direct:xmlIn", c);
        return consumerTemplate.receiveBody("seda:output", String.class);
        
    }
}

The controller contains a single method named xmlToJson, which is annotated with @RequestMapping. This annotation maps the method to the /xml endpoint and specifies that it should handle HTTP POST requests with a media type of application/xml.

The method takes a single parameter of type Customer. The @RequestBody annotation indicates that this parameter should be deserialized from the request body, which is expected to be in XML format.

The producerTemplate.sendBody method sends the c object to a Camel route with the ID xmlIn using the direct component.

The return statement uses the consumerTemplate.receiveBody method to receive the response from the Camel route with the ID output using the seda component. This response is expected to be in string format, which is then returned as the response body.

Testing the application

Firstly, start the Spring Boot application:

mvn install spring-boot:run

You can test the application with any REST Client, for example with curl:

curl -X POST   http://localhost:8080/xml   -H 'Content-Type: application/xml'   -d '<?xml version="1.0" encoding="UTF-8"?><customer><firstName>John</firstName><lastName>Doe</lastName></customer>'

As you can see, the Route performs all the following steps:

1) Serializes the Request in a Customer POJO

2) Marshals the Customer POJO in XML

3) Unmarshals the XML in JSON

4) Returns the JSON Payload in the Response

Source code for this article: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel-json-xml

Found the article helpful? if so please follow us on Socials
Twitter Icon       Facebook Icon       LinkedIn Icon       Mastodon Icon