Parameter Binding Annotations
The bean parameter binding annotations from Camel are as follows:
Annotation | Meaning | Parameter |
---|---|---|
|
To bind to an inbound message body |
|
|
To bind to an message header |
String name of the header |
|
To bind to the Map of the message headers |
|
|
To bind to a named property on the exchange |
String name of the property |
|
To bind to the exchange property map on the exchange |
|
|
To bind to an Exception set on the exchange |
Annotations can be used to define an Expression or to extract various headers, properties or payloads from a Message when invoking a bean method (see Bean Integration for more detail of how to invoke bean methods) together with being useful to help disambiguate which method to invoke.
If no annotations are used then Camel assumes that a single parameter is the body of the message. Camel will then use the Type Converter mechanism to convert from the expression value to the actual type of the parameter.
Using bean parameter binding annotations
In this example below we have a @Consume
consumer (like message driven)
that consumes JMS messages from the activemq queue. We use the @Header
and @Body
parameter binding annotations to bind from the JMSMessage to
the method parameters.
public class MyBean {
@Consume("activemq:my.queue")
public void doSomething(@Header("JMSCorrelationID") String correlationID, @Body String body) {
// process the inbound message here
}
}
In the above Camel will extract the value of
Message.getJMSCorrelationID()
, then using the
Type Converter to adapt the value to the type
of the parameter if required - it will inject the parameter value for
the correlationID parameter. Then the payload of the message will be
converted to a String and injected into the body parameter.
You don’t necessarily need to use the @Consume annotation if you don’t
want to as you could also make use of the Camel DSL to
route to the bean’s method as well.
|
Using the DSL to invoke the bean method
Here is another example which does not use POJO Consuming annotations but instead uses the DSL to route messages to the bean method
public class MyBean {
public void doSomething(@Header("JMSCorrelationID") String correlationID, @Body String body) {
// process the inbound message here
}
}
The routing DSL then looks like this
from("activemq:someQueue").
to("bean:myBean");
Here myBean would be looked up in the Registry then the body of the message would be used to try figure out what method to call.
If you want to be explicit you can use:
from("activemq:someQueue").
to("bean:myBean?methodName=doSomething");
And here we have a nifty example for you to show some great power in Camel. You can mix and match the annotations with the normal parameters, so we can have this example with annotations and the Exchange also:
public class MyBean {
public void doSomething(@Header("user") String user, @Body String body, Exchange exchange) {
exchange.getIn().setBody(body + "MyBean");
}
}
Annotation Based Expression Language
You can also use any of the Languages supported in Camel to bind expressions to method parameters when using Bean Integration. For example, you can use any of these annotations:
Annotation | Description |
---|---|
|
Inject a Bean expression |
|
Inject a Constant expression |
|
Inject a Groovy expression |
|
Inject a Header expression |
|
Inject an Simple expression |
|
Inject an XPath expression |
The table above only list some of the commonly used languages. You can find a list of all supported Languages which each have their own annotation that can be used.
It is required to include the JAR of the language, for example camel-groovy
,
or camel-jsonpath
to use the @JSonPath
annotation.
Here is an example how to use @XPath
:
public class Foo {
@Consume("activemq:my.queue")
public void doSomething(@XPath("/foo/bar/text()") String correlationID, @Body String body) {
// process the inbound message here
}
}
Advanced example using @Bean
And an example of using the the @Bean
binding annotation,
where you can call a POJO to supply
the parameter value:
public class MyBean {
@Consume("activemq:my.queue")
public void doSomething(@Bean("myCorrelationIdGenerator") String correlationID, @Body String body) {
// process the inbound message here
}
}
When a message is consumed from the activemq queue, then Camel will invoke the doSomething
method. The parameter with @Bean
is telling Camel to call yet another bean that
computes the correlation id parameter:
public class MyIdGenerator {
private UserManager userManager;
public String generate(@Header(name = "user") String user, @Body String payload) throws Exception {
User user = userManager.lookupUser(user);
String userId = user.getPrimaryId();
String id = userId + generateHashCodeForPayload(payload);
return id;
}
}
The POJO MyIdGenerator has one public method that
accepts two parameters. We have also annotated this one with the
@Header
and @Body
annotations to help Camel know what to bind here from
the Exchange being processed.
Of course this could be simplified a lot if you for instance just have a simple id generator. But we wanted to demonstrate that you can use the Bean Binding annotations anywhere.
public class MySimpleIdGenerator {
public static int generate() {
// generate a unique id
return 123;
}
}
And finally we just need to remember to have our bean registered in the Registry:
For example in Sprint XML:
<bean id="myCorrelationIdGenerator" class="com.mycompany.MySimpleIdGenerator"/>
Example using Groovy
In this example we have an Exchange that has a User object stored in the in header. This User object has methods to get some user information. We want to use Groovy to inject an expression that extracts and concats the fullname of the user into the fullName parameter.
public class MyBean {
public void doSomething(@Groovy("$request.header['user'].firstName $request.header['user'].familyName") String fullName, @Body String body) {
// process the inbound message here
}
}
Groovy supports GStrings that is like a template where we can insert $
placeholders that will be evaluated by Groovy.