Transform Message Content (Route Definition)

Apache Camel supports a variety of approaches to transforming message content. In addition to a simple native API for modifying message content, Apache Camel supports integration with several different third-party libraries and transformation standards.

Simple Message Transformations

The DSL associated with Camel have a built-in API that enables you to perform simple transformations on incoming and outgoing messages. For example, the rule shown below will append the text of “World” to the end of an incoming message body.

from("SourceURL").setBody(body().append(" World!")).to("TargetURL");

NOTE: The use of the setBody command to replace the content of the incoming message.

API for simple transformations

We can utilize the following API classes to perform simple transformations of the message content in a router rule:

  • org.apache.camel.model.ProcessorDefinition

    org.apache.camel.builder.Builder

    org.apache.camel.builder.ValueBuilder

ProcessorDefinition class

The org.apache.camel.model.ProcessorDefinition class defines the DSL commands you can insert directly into a router rule:

Method

Description

Method

Description

Type convertBodyTo(Class type)

Converts the IN message body to the specified type.

Type removeFaultHeader(String name)

Adds a processor which removes the header on the FAULT message.

Type removeHeader(String name)

Adds a processor which removes the header on the IN message.

Type removeProperty(String name)

Adds a processor which removes the exchange property.

ExpressionClause<ProcessorDefinition<Type>> setBody()

Adds a processor which sets the body on the IN message.

Type setFaultBody(Expression expression)

Adds a processor which sets the body on the FAULT message.

Type setFaultHeader(String name, Expression expression)

Adds a processor which sets the header on the FAULT message.

ExpressionClause<ProcessorDefinition<Type>> setHeader(String name)

Adds a processor which sets the header on the IN message.

Type setHeader(String name, Expression expression)

Adds a processor which sets the header on the IN message.

ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name)

Adds a processor which sets the header on the OUT message.

Type setOutHeader(String name, Expression expression)

Adds a processor which sets the header on the OUT message.

ExpressionClause<ProcessorDefinition<Type>> setProperty(String name)

Adds a processor which sets the exchange property.

Type setProperty(String name, Expression expression)

Adds a processor which sets the exchange property.

ExpressionClause<ProcessorDefinition<Type>> transform()

Adds a processor which sets the body on the OUT message.

Type transform(Expression expression)

Adds a processor which sets the body on the OUT message.

Builder class

The org.apache.camel.builder.Builder class will provide us access to message content in contexts where expressions or predicates are expected. Thus, Builder methods are typically invoked in the arguments of DSL commands.

ValueBuilder class

The org.apache.camel.builder.ValueBuilder class will enable us to modify values returned by the Builder methods. In other words, the methods in ValueBuilder provide a simple way of modifying message content.

Marshalling and Unmarshalling

We are able to convert between low-level and high-level message formats using these commands:

  • marshal() —  Converts a high-level data format to a low-level data format.

    unmarshal()  —  Converts a low-level data format to a high-level data format.

Apache Camel supports marshalling and unmarshalling of the following data formats:

  • Java serialization

  • JAXB

  • XMLBeans

  • XStream

Java serialization

This process will enable us to convert a Java object to a blob of binary data. Using this data format, unmarshalling converts a binary blob to a Java object, and marshalling converts a Java object to a binary blob. For example, to read a serialized Java object from an endpoint, SourceURL, and convert it to a Java object, you use a rule like the following:

from("SourceURL").unmarshal().serialization() .<FurtherProcessing>.to("TargetURL");

Or alternatively, in Spring XML:

<route> <from uri="SourceURL"/> <unmarshal> <serialization/> </unmarshal> <to uri="TargetURL"/> </route>

JAXB

This option provides a mapping between XML schema types and Java types With the use of JAXB, unmarshalling converts an XML data type to a Java object, and marshalling converts a Java object to an XML type.

Before we can begin to use JAXB data formats, we must compile our XML schema with a JAXB compiler to generate the necessary Java classes that represent the XML data types in the schema (known as binding the schema). Once the schema is bound, we can define a rule to unmarshal XML data to a Java object, using code like the following:

NOTE: Where GeneratedPackagename is the name of the Java package generated by the JAXB compiler, that will contain the Java classes representing your XML schema.

Or alternatively, in Spring XML:

XMLBeans

Another alternative for our mapping between XML schema types and Java types is the use of XMLBeans. Through it usage, unmarshalling converts an XML data type to a Java object and marshalling converts a Java object to an XML data type. For example, to unmarshal XML data to a Java object using XMLBeans, use code like the following:

Or alternatively, in Spring XML:

Endpoint Bindings

What do we mean when we talk about binding? With Apache Camel, a binding is a means of wrapping an endpoint in a contract (ie. by applying a Data Format, a Content Enricher or a validation step). In this scenario, a condition or transformation is applied to the messages coming in, and a complementary condition or transformation is applied to the messages going out.

DataFormatBinding

The use of the DataFormatBinding class is quite useful for those situations where you want to define a binding that marshals and unmarshals a particular data format. In this case, all that you need to do to create a binding is to create a DataFormatBinding instance, passing a reference to the relevant data format in the constructor.

For example, the following XML DSL code snippet shows a binding (with ID, jaxb) that is capable of marshalling and unmarshalling the JAXB data format when it is associated with an Apache Camel endpoint:

 

Binding URI

To link a binding with an endpoint, we can prefix the endpoint URI with binding:NameOfBinding, where NameOfBinding value is the bean ID of the binding (ie. ID of a binding bean created in Spring XML).

For example, the following shows how to associate JMS endpoints with the JAXB binding: