Velocity component
The Velocity component uses Apache Velocity, a Java-based template engine that allows you to create templates for your message bodies. It provides a language to reference objects and variables defined in the current context.
The SetBody component is the successor to the Velocity component. Use the SetBody component to build a body in your flow, and use the Velocity component purely for its templating capabilities.
You cannot use Simple expressions in the Velocity template, use the SetBody component instead.
Configuration
The Velocity component has the following basic configuration options:
Template
The Velocity template that should be evaluated for each message passing through the component.
Be aware that the Velocity templating languages interprets certain characters as syntax.
For instance, combinations of #
and *
symbols are considered comments or comment sections in the Velocity template language. For instance, an XML or JSON body will be truncated after #*
.
Use a Replace component before the Velocity component if you need to replace certain character (combinations).
Using Velocity
Headers to XML
In the example below demonstrates how to use a Velocity template to map message headers to an XML format. The headers First
and Last
, with value John
and Doe
, are available in the message passing through the Velocity component.
Use the tabs to see the Velocity template and the resulting XML:
- Velocity headers template
- Result XML
<userinfo>
<firstname>$headers.First</firstname>
<lastname>$headers.Last</lastname>
</userinfo>
<userinfo>
<firstname>John</firstname>
<lastname>Doe</lastname>
</userinfo>
JSON to JSON
The example below shows how to use a Velocity template to transform a JSON object into another JSON object with a different layout. Use the tabs below to see the source JSON, the Velocity template and the resulting JSON when all the data is available in the source JSON:
- Source JSON Full
- Velocity template
- Result JSON
{
"firstname": "John",
"lastname": "Doe",
"company": "MyCompany",
"email": "john.doe@example.com",
"age": 30,
"address": {
"city": "New York",
"zip": "10001"
}
}
{
"userInfo": {
#if ($body.firstname && $body.lastname) "fullName": "$body.firstname $body.lastname", #else #end
"email": #if ($body.email) "$body.email" #else null #end,
"profile": {
"company": "$!body.company",
"age": $body.age
},
"location": {
"city": "$body.address.city",
"zipCode": "$body.address.zip"
}
}
}
{
"userInfo": {
"fullName": "John Doe",
"email": "john.doe@example.com",
"profile": {
"company": "MyCompany",
"age": 30
},
"location": {
"city": "New York",
"zipCode": "10001"
}
}
}
When the source JSON is incomplete, the transformation behaves differently. Notice how the Velocity template evaluates variables and the impact on the resulting JSON:
- Source JSON Part
- Velocity template
- Result JSON
{
"firstname": "",
"lastname": "Doe",
"company": "",
"email": "",
"address": {
"city": "New York",
"zip": "10001"
}
}
{
"userInfo": {
#if ($body.firstname && $body.lastname) "fullName": "$body.firstname $body.lastname", #else #end
"email": #if ($body.email) "$body.email" #else null #end,
"profile": {
"company": "$!body.company",
"age": $body.age
},
"location": {
"city": "$body.address.city",
"zipCode": "$body.address.zip"
}
}
}
{
"userInfo": {
"email": null,
"profile": {
"company": "",
"age": $age
},
"location": {
"city": "New York",
"zipCode": "10001"
}
}
}
JSON map
To ensure the Velocity template correctly sets variables from JSON keys, the source JSON must be mapped. Use the following Groovy (4.0) script before the Velocity component if the variables are not correctly initialized:
// Import necessary JSON handling classes
import groovy.json.JsonSlurper
// Parse the incoming request body as JSON
def body = new JsonSlurper().parseText(request.getBody(java.lang.String.class))
XML to JSON
The example below shows how to use a Velocity template to transform XML into JSON with the same layout as the JSON-to-JSON example. Use the tabs below to see the source XML, the Velocity template, and the resulting JSON when all data is available:
- Source XML Full
- Velocity template
- Result JSON
<root>
<firstname>John</firstname>
<lastname>Doe</lastname>
<company>MyCompany</company>
<email>john.doe@example.com</email>
<age>30</age>
<address>
<city>New York</city>
<zip>10001</zip>
</address>
</root>
{
"userInfo": {
#if ($body.firstname && $body.lastname) "fullName": "$body.firstname $body.lastname", #else #end
"email": #if ($body.email) "$body.email" #else null #end,
"profile": {
"company": "$!body.company",
"age": $body.age
},
"location": {
"city": "$body.address.city",
"zipCode": "$body.address.zip"
}
}
}
{
"userInfo": {
"fullName": "John Doe",
"email": "john.doe@example.com",
"profile": {
"company": "MyCompany",
"age": 30
},
"location": {
"city": "New York",
"zipCode": "10001"
}
}
}
When the source XML is incomplete, the transformation behaves differently. Notice how the Velocity template evaluates variables and the impact on the resulting JSON:
- Source XML Part
- Velocity template
- Result JSON
<root>
<firstname></firstname>
<lastname>Doe</lastname>
<company></company>
<email />
<address>
<city>New York</city>
<zip>10001</zip>
</address>
</root>
{
"userInfo": {
#if ($body.firstname && $body.lastname) "fullName": "$body.firstname $body.lastname", #else #end
"email": #if ($body.email) "$body.email" #else null #end,
"profile": {
"company": "$!body.company",
"age": $body.age
},
"location": {
"city": "$body.address.city",
"zipCode": "$body.address.zip"
}
}
}
{
"userInfo": {
"email": null,
"profile": {
"company": "",
"age": $age
},
"location": {
"city": "New York",
"zipCode": "10001"
}
}
}
XML map
To ensure the Velocity template correctly sets variables from XML elements, the source XML must be mapped. Use the following Groovy (4.0) script before the Velocity component if the variables are not correctly initialized:
// Import necessary XML handling classes
import groovy.xml.*
// Parse the XML with XmlSlurper
def parsedXml = new XmlSlurper().parseText(request.body)
// Method to convert XML structure to Map
def xmlToMap(node) {
def result = [:] // Create an empty map
node.children().each { child ->
// If the child node has children, recursively call xmlToMap
if (child.children().size() > 0) {
result[child.name()] = xmlToMap(child)
} else {
// If the node has no children, add the value
result[child.name()] = child.text()
}
}
return result
}
// Convert the parsed XML to a Map
def resultMap = xmlToMap(parsedXml)
resultMap
Because the layouts of the JSON and XML examples in the JSON to JSON and XML to JSON sections result in identical maps, their Velocity templates are exactly the same.