Parameter Binding Annotations has been edited by willem jiang (Feb 04, 2009).

Change summary:

Fixed the typos of @Header

(View changes)

Content:

Parameter Binding Annotations

camel-core

The annotations below are all part of camel-core and thus does not require camel-spring or Spring. These annotations can be used with the Bean component or when invoking beans in the DSL

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.

The core annotations are as follows

Annotation Meaning Parameter
@Body To bind to an inbound message body  
@ExchangeException To bind to an Exception set on the exchange (Camel 2.0)  
@Header To bind to an inbound message header String name of the header
@Headers To bind to the Map of the inbound message headers  
@OutHeaders To bind to the Map of the outbound message headers  
@Property To bind to a named property on the exchange String name of the property
@Properties To bind to the property map on the exchange  

The follow annotations @Headers, @OutHeaders and @Properties binds to the backing java.util.Map so you can alter the content of these maps directly, for instance using the put method to add a new entry. See the OrderService class at Exception Clause for such an example.

Example

In this example below we have a @MessageDriven consumer 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 Foo {
	
    @MessageDriven(uri = "activemq:my.queue")
    public void doSomething(@Header(name = "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 need to use the @MessageDriven annotation; as you could use the Camel DSL to route to the beans method

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 Foo {
    public void doSomething(@Header(name = "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 (such as JNDI or the Spring ApplicationContext), 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 void doSomething(@Header(name = "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
@Bean Inject a Bean _expression_
@BeanShell Inject a BeanShell _expression_
@Constant Inject a Constant _expression_
@EL Inject an EL _expression_
@Groovy Inject a Groovy _expression_
@Header Inject a Header _expression_
@_javascript_ Inject a _javascript_ _expression_
@OGNL Inject an OGNL _expression_
@PHP Inject a PHP _expression_
@Python Inject a Python _expression_
@Ruby Inject a Ruby _expression_
@Simple Inject an Simple _expression_
@XPath Inject an XPath _expression_
@XQuery Inject an XQuery _expression_

Example:

public class Foo {
	
    @MessageDriven(uri = "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 use a POJO where you can do whatever java code you like:

public class Foo {
	
    @MessageDriven(uri = "activemq:my.queue")
    public void doSomething(@Bean("myCorrelationIdGenerator") String correlationID, @Body String body) {
		// process the inbound message here
    }
}

And then we can have a spring bean with the id myCorrelationIdGenerator where we can compute the id.

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. However we have also annotated this one with the @Header and @Body annotation to help Camel know what to bind here from the Message 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 Spring Registry:

<bean id="myCorrelationIdGenerator" class="com.mycompany.MyIdGenerator"/>

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 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.

Reply via email to