Apache camel: Xml file to JSON file.
Published: 2022-07-29 18:40:28

Hi there,

I started learning Apache Camel a few days ago and was having difficulty with this simple case: Creating a JSON file from an XML file.

## Problem 1: Old version

I picked up a project from a course I was taking. And the version used in this course was out of date. The course was using the dependency 'camel-xmljson,' which has since been removed in the new version.

## Upgrading project

So I've decided to upgrade project to use `Java 17` and apache camel version `3.18.0`.

To do this, I've needed to import new dependencies on project:

```
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jaxb</artifactId>
    <version>${camel-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jackson</artifactId>
    <version>${camel-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jacksonxml</artifactId>
    <version>${camel-version}</version>
</dependency>
```

## Refactoring the code

After import the new dependencies, I needed to refactor my code.

### Before refactoring

The code was as follows:

```
public static void main(String[] args) throws Exception {

		CamelContext context = new DefaultCamelContext();
		context.addRoutes(new RouteBuilder() {

			@Override
			public void configure() throws Exception {

				from("file:pedidos?delay=5s&noop=true").
					split().
						xpath("/pedido/itens/item").
					filter().
						xpath("/item/formato[text()='EBOOK']").
					marshal().xmljson().
					log("${id} - ${body}").
					setHeader(Exchange.FILE_NAME, simple("${file:name.noext}-${header.CamelSplitIndex}.json")).
				to("file:saida");
			}
			
		});

		context.start();
		Thread.sleep(20000);
		context.stop();
	}
```

### After refactoring

And now I needed to do this:

```
public static void main(String[] args) throws Exception {

		try (CamelContext context = new DefaultCamelContext()) {
			JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
			jacksonDataFormat.setPrettyPrint(true);
			jacksonDataFormat.enableFeature(SerializationFeature.WRAP_ROOT_VALUE);

			context.addRoutes(new RouteBuilder() {

				@Override
				public void configure() throws Exception {

					from("file:input?delay=5s&noop=true")
						.filter()
							.xpath("/pedido/itens/item/formato[text()='EBOOK']")
						.unmarshal().jacksonXml(Pedido.class)
						.marshal(jacksonDataFormat)
						.setHeader(Exchange.FILE_NAME, simple("${file:name.noext}.json"))
						.to("file:output");
				}

			});

			context.start();
			Thread.sleep(20000);
			context.stop();
		}
	}
```

I needed to use some jackson annotations in "Pedido.java":

```
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "pedido")
public class Pedido {
	
	@JacksonXmlProperty(localName = "id")
	private String id;
	@JacksonXmlProperty(localName = "dataCompra")
	private String dataCompra;
	@JacksonXmlProperty(localName = "itens")
	private Itens itens;
	@JacksonXmlProperty(localName = "pagamento")
	private Pagamento pagamento;

....
// getters and setters

```

Note that 'Before refactoring,' I only needed to use'marshal().xmljson(),' and 'After refactoring,' I needed to do the following:

```
JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
jacksonDataFormat.setPrettyPrint(true);
jacksonDataFormat.enableFeature(SerializationFeature.WRAP_ROOT_VALUE);

.unmarshal().jacksonXml(Pedido.class)
.marshal(jacksonDataFormat)
```

## Conclusion

Well, this was the solution I discovered.

I know, there must be a better method, and if you know, left your comment and help me improve. :D

Thank you very much and see you!