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