Search code examples
apache-camelapache-camel-3

Camel set body to object with header expression


Is it possible to set a response body to an object and pass in a camel header property. I can achieve this in a processor but I'd rather do it in line of the route.

.setBody(constant(
        new Foo()
        .withOne("HelloWorld")
        .withTwo(simple("Header property is ${header.uniqueProperty}").toString())
))

With the above code I get a response of:

<foo>
  <one>HelloWorld</one>
  <two>Header property is ${header.uniqueProperty}</two>
</foo>

Here is my POJO

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private String one;
    private String two;

    public String getOne() {
    return one;
    }

    public void setOne(final String one) {
    this.one = one;
    }

    public String getTwo() {
    return two;
    }

    public void setTwo(final String two) {
    this.two = two;
    }

    public Foo withOne(final String one) {
    setOne(one);
    return this;
    }

    public Foo withTwo(final String two) {
    setTwo(two);
    return this;
    }
}

Solution

  • constant() probably won't work for you, since you probably want this dynamically evaluated for every exchange that passes through. Since you need to set the body to a newly instantiated object, you need a mechanism that's capable of this. You mentioned you want to avoid a processor, but I'd like to point out how simple this could be done in the route:

    .setBody(exchange -> new Foo()
            .withOne("HelloWorld")
            .withTwo(simple("Header property is " + exchange.getIn().getHeader("uniqueProperty")))
    )
    

    Edit: Actually this is not a processor. We're just passing a lambda (Function) to setBody().

    If you're in a Spring environment, you could use spring expression language:

    .setBody().spel("#{new Foo()" +
        ".withOne('HelloWorld')" +
        ".withTwo(simple('Header property is ' + request.headers.uniqueProperty))}");