Camel Components

SpEL

Since Camel 2.7

Camel allows Spring Expression Language (SpEL) to be used as an Expression or Predicate in the DSL or XML Configuration.

It is recommended to use SpEL in Spring runtimes. Although you can use SpEL in other runtimes, there is some functionality that SpEL can only do in a Spring runtime.

SpEL Options

The SpEL language supports the following options which are listed below.

Name Default Java Type Description

resultType (common)

String

The class of the result type (type from output).

trim (advanced)

true

Boolean

Whether to trim the source code to remove leading and trailing whitespaces and line breaks.

resolveResource (advanced)

false

Boolean

Whether a result of the expression that is a String starting with resource: is loaded as a resource and its content becomes the result, e.g. a script that returns resource:file:order.json or resource:classpath:templates/order.json (a name without a scheme is a classpath resource). Off by default; the resource: prefix on the expression text itself is always resolved. Applies to the expression used as a value, not as a predicate.

Message Body

The message body at each side of the SpEL language: Expression input is the body its expressions can read, and Expression result what they return.

Side Body Description

Expression input

any

The body as it is, in body, request.body or message.body.

Expression result

unknown

What the expression returns, and text when text surrounds the #{ } parts.

The bodies are the ones with the default options. A side that is not listed is not known, and tooling does not guess it. The carriers are described in the Camel Catalog.

Variables

The following Camel related variables are made available:

Variable Type Description

this

RootObject

the root object, whose properties are the variables below

context

CamelContext

the CamelContext

exchange

Exchange

the Exchange

exchangeId

String

the exchange id

exception

Throwable

the Exchange exception (if any)

request

Message

the message

message

Message

the message

body

Object

the message body

headers

Map

the message headers

getHeader(name)

Object

the message header by the given name

getHeader(name, type)

Type

the message header by the given name as the given type

properties

Map

the exchange properties

getProperty(name)

Object

the exchange property by the given name

getProperty(name, type)

Type

the exchange property by the given name as the given type

variables

Map

the exchange variables

getVariable(name)

Object

the exchange variable by the given name

getVariable(name, type)

Type

the exchange variable by the given name as the given type

getHeader, getProperty and getVariable are methods on the root object, so they are called by their full name, as in {getHeader('foo')} or {getVariable('foo')}. The maps can be read as {headers.foo} or {variables['foo']}. getVariable also resolves global and route variables, such as #{getVariable('global:foo')}, which are not in the variables map.

Example

You can use SpEL as an expression for Recipient List or as a predicate inside a Message Filter:

  • Java

  • XML

  • YAML

from("direct:foo")
    .filter().spel("#{request.headers.foo == 'bar'}")
    .to("direct:bar");
<route>
  <from uri="direct:foo"/>
  <filter>
    <spel>#{request.headers.foo == 'bar'}</spel>
    <to uri="direct:bar"/>
  </filter>
</route>
- route:
    from:
      uri: direct:foo
      steps:
        - filter:
            expression:
              spel:
                expression: "#{request.headers.foo == 'bar'}"
            steps:
              - to:
                  uri: direct:bar

Expression templating

SpEL expressions need to be surrounded by #{ } delimiters since expression templating is enabled. This allows you to combine SpEL expressions with regular text and use this as an extremely lightweight template language.

For example, if you construct the following route:

Java-only: static method import for spel expression
from("direct:example")
    .setBody(spel("Hello #{request.body}! What a beautiful #{request.headers['dayOrNight']}"))
    .to("mock:result");

In the route above, notice spel is a static method which we need to import from org.apache.camel.language.spel.SpelExpression.spel, as we use spel as an Expression passed in as a parameter to the setBody method. Though if we use the fluent API, we can do this instead:

  • Java

  • XML

  • YAML

from("direct:example")
    .setBody().spel("Hello #{request.body}! What a beautiful #{request.headers['dayOrNight']}")
    .to("mock:result");
<route>
  <from uri="direct:example"/>
  <setBody>
    <spel>Hello #{request.body}! What a beautiful #{request.headers['dayOrNight']}</spel>
  </setBody>
  <to uri="mock:result"/>
</route>
- route:
    from:
      uri: direct:example
      steps:
        - setBody:
            expression:
              spel:
                expression: 'Hello #{request.body}! What a beautiful #{request.headers[''dayOrNight'']}'
        - to:
            uri: mock:result

Notice we now use the spel method from the setBody() method. And this does not require us to statically import the spel method.

Then we send a message with the string "World" in the body, and a header dayOrNight with value day:

Java-only: ProducerTemplate usage
template.sendBodyAndHeader("direct:example", "World", "dayOrNight", "day");

The output on mock:result will be "Hello World! What a beautiful day"

Bean integration

You can reference beans defined in the Registry in your SpEL expressions. For example, if you have a bean named "foo" registered in the Spring ApplicationContext. You can then invoke the "bar" method on this bean like this:

#{@foo.bar == 'xyz'}

Loading script from external resource

You can externalize the script and have Apache Camel load it from a resource such as "classpath:", "file:", or "http:". This is done using the following syntax: "resource:scheme:location", e.g., to refer to a file on the classpath you can do:

Java-only: fluent API for loading SpEL from resource
.setHeader("myHeader").spel("resource:classpath:myspel.txt")