camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Bean Binding
Date Mon, 25 Jul 2011 19:30:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Bean+Binding">Bean
Binding</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (24)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">3</span><span
class="diff-added-chars"style="background-color: #dfd;">2</span>.</span> Bean
Binding <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The Bean Binding in Camel
defines both which methods are invoked and also how the [Message] is converted into the parameters
of the method when it is invoked. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">4</span><span
class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Choosing
the method to invoke <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The binding of a Camel
[Message] to a bean method call can occur in different ways, order if importance: <br>
<br></td></tr>
            <tr><td class="diff-changed-lines" >* if the message contains the
header *CamelBeanMethodName* <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">(*org.apache.camel.MethodName*
in Camel 1.x)</span> then that method is invoked, converting the body to whatever the
argument is to the method. <br></td></tr>
            <tr><td class="diff-unchanged" >** From *Camel 2.8* onwards you can
qualify parameter types to exact pin-point which method to use when using overloaded methods
with the same name (see further below for more details). <br></td></tr>
            <tr><td class="diff-changed-lines" >** From *Camel 2.9* onwards you
can specify parameter values directly in the method <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">syntax</span>
<span class="diff-added-words"style="background-color: #dfd;">option</span> (see
further below for more details). <br></td></tr>
            <tr><td class="diff-changed-lines" >* the method name can be specified
explicitly in the [DSL] or when using [POJO Consuming] <span class="diff-added-words"style="background-color:
#dfd;">or [POJO Producing]</span> <br></td></tr>
            <tr><td class="diff-changed-lines" >* <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">*Camel
2.0:*</span> if the bean has a method that is marked with {{@Handler}} annotation then
that method is selected <br></td></tr>
            <tr><td class="diff-unchanged" >* if the bean can be converted to
a [Processor] using the [Type Converter] mechanism then this is used to process the message.
This mechanism is used by the [ActiveMQ] component to allow any JMS MessageListener to be
invoked directly by Camel without having to write any integration glue code. You can use the
same mechanism to integrate Camel into any other messaging/remoting frameworks. <br>*
if the body of the message can be converted to a [BeanInvocation|http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/bean/BeanInvocation.html]
(the default payload used by the [ProxyHelper|http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/bean/ProxyHelper.html])
- then that its used to invoke the method and pass the arguments <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">4</span><span
class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Parameter
binding <br></td></tr>
            <tr><td class="diff-unchanged" >When a method have been chosen to
be invoked Camel will bind to the parameters of the method. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >- {{org.apache.camel.Exchange}} <br>-
{{org.apache.camel.Message}} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">-
*Camel 2.0:* {{org.apache.camel.CamelContext}} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">-
{{org.apache.camel.CamelContext}} <br></td></tr>
            <tr><td class="diff-unchanged" >- {{org.apache.camel.TypeConverter}}
<br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">-
*Camel 2.0:* {{org.apache.camel.spi.Registry}}  <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">-
{{org.apache.camel.spi.Registry}}  <br></td></tr>
            <tr><td class="diff-unchanged" >- {{java.lang.Exception}}  <br>
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >So what about headers and other
stuff? Well now it gets a bit tricky so we can use annotations to help <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">us.
See next section for details.</span> <span class="diff-added-words"style="background-color:
#dfd;">us, or specify the binding in the method name option.</span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">See
the following sections for more details. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">4</span><span
class="diff-added-chars"style="background-color: #dfd;">3</span>.</span> Binding
Annotations <br></td></tr>
            <tr><td class="diff-unchanged" > <br>You can use the [Parameter
Binding Annotations] to customize how parameter values are created from the [Message] <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h4. @Handler <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">*Available
as of Camel 2.0* <br> <br></td></tr>
            <tr><td class="diff-unchanged" >You can mark a method in your bean
with the @Handler annotation to indicate that this method should be used for [Bean Binding].
<br>This has the advantage as you do not have to specify the method name in the Camel
route. And thus you do not run into problems when you rename the method name using an IDE
that don&#39;t find all references. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h4.
POJO consuming <br>For example you could use [POJO Consuming] to write a bean like this
<br>{info:title=@Consume requires camel-spring} <br>Using the {{@Consume}} annotations
requires *camel-spring* that uses the {{org.apache.camel.spring.CamelBeanPostProcessor}} to
perform the setup for this consumer and the needed bean bindings. <br>{info} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Parameter binding using method option <br>*Available as of Camel 2.9* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{tip:title=@MessageDriven
is @deprecated} <br>The @MessageDriven has been replaced with @Consume in Camel 1.5.0
or newer. Its now marked as @deprecated and will be removed in Camel 2.0. <br>{tip}
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Camel
uses the following rules to determine if its a parameter value in the method option <br>-
The value is either {{true}} or {{false}} which denotes a boolean value <br>- The value
is a numeric value such as {{123}} or {{7}} <br>- The value is a String enclosed with
either single or double quotes <br>- It can be evaluated using the [Simple] language,
which means you can use eg body, header.foo and other [Simple] tokens. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{code}
<br>public class Foo { <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Any
other value is consider to be a type declaration instead, see next section about pin pointing
types for overloaded methods. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
   @Consume(uri = &quot;activemq:my.queue&quot;) <br>    public void doSomething(String
body) { <br>		// process the inbound message here <br>    } <br> <br>}
<br>{code} <br> <br>Here Camel with subscribe to an ActiveMQ queue, then
convert the message payload to a String (so dealing with TextMessage, ObjectMessage and BytesMessage
in JMS), then process this method. <br> <br> <br>h3. Using type qualifier
to pin-point method to use when having overloaded methods <br>*Available as of Camel
2.8* <br> <br>If you have a [Bean] which has overloaded methods you can now specify
the parameter types in the method name, so Camel can match the method you intend to use. <br>Given
the following bean: <br>{snippet:id=e1|lang=java|title=MyBean|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>Then the {{MyBean}} has 2 overloaded methods with the names {{hello}}
and {{times}}. So if we want to use the method which has 2 parameters we can do as follows
in the Camel route: <br>{snippet:id=e2|lang=java|title=Invoke 2 parameter method|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>We can also use a {{*}} as wildcard so we can just say we want to execute
the method with 2 parameters we do <br>{snippet:id=e3|lang=java|title=Invoke 2 parameter
method using wildcard|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>By default Camel will match the type name using the simple name, eg any
leading package name will be disregarded. However if you want to match using the FQN then
specify the FQN type and Camel will leverage that. So if you have a {{com.foo.MyOrder}} and
you want to match against the FQN, and *not* the simple name &quot;MyOrder&quot; then
do as follows: <br>{code} <br>   .bean(OrderService.class, &quot;doSomething(com.foo.MyOrder)&quot;)
<br>{code} <br> <br>{info} <br>The current implementation for choosing
method using type qualifiers only compares the type names. It does *not* check any {{instanceof}}
checks or the likes. The type name must match exactly, as its using a string equals comparison.
<br>{info} <br> <br> <br>h3. Specifying parameter values in method
name syntax <br>*Available as of Camel 2.9* <br> <br></td></tr>
            <tr><td class="diff-unchanged" >When invoking a [Bean] you can instruct
Camel to invoke a specific method by providing the method name. For example as shown below:
<br>{code} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{tip}
<br>Its a good idea to use ${ } placeholders in the method option as shown in the example
above. This makes it clear to the read, that this is a [Simple] token and the actual value
is dynamic computed form the [Exchange] being routed. <br>{tip} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >You can also pass in other fixed values
than boolean values. For example to pass in an String and integer do as follows: <br>{code}
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >   .to(&quot;bean:orderService?method=doSomething(${body.asXml},
${header.high})&quot;) <br>{code} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
<br> <br>h3. Using type qualifier to pin-point method to use when having overloaded
methods <br>*Available as of Camel 2.8* <br> <br>If you have a [Bean] which
has overloaded methods you can now specify the parameter types in the method name, so Camel
can match the method you intend to use. <br>Given the following bean: <br>{snippet:id=e1|lang=java|title=MyBean|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>Then the {{MyBean}} has 2 overloaded methods with the names {{hello}}
and {{times}}. So if we want to use the method which has 2 parameters we can do as follows
in the Camel route: <br>{snippet:id=e2|lang=java|title=Invoke 2 parameter method|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>We can also use a {{*}} as wildcard so we can just say we want to execute
the method with 2 parameters we do <br>{snippet:id=e3|lang=java|title=Invoke 2 parameter
method using wildcard|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanOverloadedMethodTest.java}
<br> <br>By default Camel will match the type name using the simple name, eg any
leading package name will be disregarded. However if you want to match using the FQN then
specify the FQN type and Camel will leverage that. So if you have a {{com.foo.MyOrder}} and
you want to match against the FQN, and *not* the simple name &quot;MyOrder&quot; then
do as follows: <br>{code} <br>   .bean(OrderService.class, &quot;doSomething(com.foo.MyOrder)&quot;)
<br>{code} <br> <br>{info} <br>Camel currently only supports either
specifying parameter binding or type per parameter in the method name option. You *cannot*
specify both at the same time, such as  <br>{code} <br>doSomething(com.foo.MyOrder
${body}, boolean ${header.high}) <br>{code} <br>This may change in the future.
<br>{info} <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="BeanBinding-BeanBinding"></a>Bean Binding</h2>

<p>The Bean Binding in Camel defines both which methods are invoked and also how the
<a href="/confluence/display/CAMEL/Message" title="Message">Message</a> is converted
into the parameters of the method when it is invoked.</p>

<h3><a name="BeanBinding-Choosingthemethodtoinvoke"></a>Choosing the method
to invoke</h3>

<p>The binding of a Camel <a href="/confluence/display/CAMEL/Message" title="Message">Message</a>
to a bean method call can occur in different ways, order if importance:</p>

<ul>
	<li>if the message contains the header <b>CamelBeanMethodName</b> then
that method is invoked, converting the body to whatever the argument is to the method.
	<ul>
		<li>From <b>Camel 2.8</b> onwards you can qualify parameter types to exact
pin-point which method to use when using overloaded methods with the same name (see further
below for more details).</li>
		<li>From <b>Camel 2.9</b> onwards you can specify parameter values directly
in the method option (see further below for more details).</li>
	</ul>
	</li>
	<li>the method name can be specified explicitly in the <a href="/confluence/display/CAMEL/DSL"
title="DSL">DSL</a> or when using <a href="/confluence/display/CAMEL/POJO+Consuming"
title="POJO Consuming">POJO Consuming</a> or <a href="/confluence/display/CAMEL/POJO+Producing"
title="POJO Producing">POJO Producing</a></li>
	<li>if the bean has a method that is marked with <tt>@Handler</tt> annotation
then that method is selected</li>
	<li>if the bean can be converted to a <a href="/confluence/display/CAMEL/Processor"
title="Processor">Processor</a> using the <a href="/confluence/display/CAMEL/Type+Converter"
title="Type Converter">Type Converter</a> mechanism then this is used to process
the message. This mechanism is used by the <a href="/confluence/display/CAMEL/ActiveMQ"
title="ActiveMQ">ActiveMQ</a> component to allow any JMS MessageListener to be invoked
directly by Camel without having to write any integration glue code. You can use the same
mechanism to integrate Camel into any other messaging/remoting frameworks.</li>
	<li>if the body of the message can be converted to a <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/bean/BeanInvocation.html"
class="external-link" rel="nofollow">BeanInvocation</a> (the default payload used
by the <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/bean/ProxyHelper.html"
class="external-link" rel="nofollow">ProxyHelper</a>) - then that its used to invoke
the method and pass the arguments</li>
	<li>otherwise the type of the method body is used to try find a method which matches;
an error is thrown if a single method cannot be chosen unambiguously.</li>
	<li>you can also use Exchange as the parameter itself, but then the return type must
be void.</li>
</ul>


<p>In case where Camel will not be able to choose a method to invoke an <tt>AmbiguousMethodCallException</tt>
is thrown. </p>

<p>By default the return value is set on the outbound message body.</p>


<h3><a name="BeanBinding-Parameterbinding"></a>Parameter binding</h3>
<p>When a method have been chosen to be invoked Camel will bind to the parameters of
the method.</p>

<p>The following Camel specific types is automatic binded:</p>
<ul class="alternate" type="square">
	<li><tt>org.apache.camel.Exchange</tt></li>
	<li><tt>org.apache.camel.Message</tt></li>
	<li><tt>org.apache.camel.CamelContext</tt></li>
	<li><tt>org.apache.camel.TypeConverter</tt></li>
	<li><tt>org.apache.camel.spi.Registry</tt></li>
	<li><tt>java.lang.Exception</tt></li>
</ul>


<p>So if you declare any of the given type above they will be provided by Camel. A <b>note</b>
on the <tt>Exception</tt> is that it will bind to the caught exception of the
<a href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a>. So
its often usable if you use a <a href="/confluence/display/CAMEL/Pojo" title="Pojo">Pojo</a>
to handle a given using using eg an <tt>onException</tt> route. </p>

<p>What is most interresting is that Camel will also try to bind the body of the <a
href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a> to the first
parameter of the method signature (albeit not of any of the types above). So if we for instance
declare e parameter as: <tt>String body</tt> then Camel will bind the IN body
to this type. Camel will also automatic type convert to the given type declared.</p>

<p>Okay lets show some examples.</p>

<p>Below is just a simple method with a body binding. Camel will bind the IN body to
the <tt>body</tt> parameter and convert it to a <tt>String</tt> type.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body)
</pre>
</div></div>

<p>And in this sample we got one of the automatic binded type as well, for instance
the <tt>Registry</tt> that we can use to lookup beans.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body, Registry registry)
</pre>
</div></div>

<p>And we can also use <a href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a>
as well:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body, Exchange exchange)
</pre>
</div></div>

<p>You can have multiple types as well</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body, Exchange exchange, TypeConverter
converter)
</pre>
</div></div>

<p>And imagine you use a <a href="/confluence/display/CAMEL/Pojo" title="Pojo">Pojo</a>
to handle a given custom exception <tt>InvalidOrderException</tt> then we can
bind that as well:<br/>
Notice we can bind to it even if we use a sub type of <tt>java.lang.Exception</tt>
as Camel still knows its an exception and thus can bind the caused exception (if any exists).</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-object">String</span>
badOrder(<span class="code-object">String</span> body, InvalidOrderException invalid)
</pre>
</div></div>

<p>So what about headers and other stuff? Well now it gets a bit tricky so we can use
annotations to help us, or specify the binding in the method name option.<br/>
See the following sections for more details.</p>

<h3><a name="BeanBinding-BindingAnnotations"></a>Binding Annotations</h3>

<p>You can use the <a href="/confluence/display/CAMEL/Parameter+Binding+Annotations"
title="Parameter Binding Annotations">Parameter Binding Annotations</a> to customize
how parameter values are created from the <a href="/confluence/display/CAMEL/Message" title="Message">Message</a></p>

<h4><a name="BeanBinding-Examples"></a>Examples</h4>

<p>For example a <a href="/confluence/display/CAMEL/Bean" title="Bean">Bean</a>
such as:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Bar {

    <span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body) {
      <span class="code-comment">// process the in body and <span class="code-keyword">return</span>
whatever you want
</span>      <span class="code-keyword">return</span> <span class="code-quote">"Bye
World"</span>;
   }
</pre>
</div></div>

<p>Or the Exchange example. Notice that the return type must be <b>void</b>
when there is only a single parameter:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Bar {

    <span class="code-keyword">public</span> void doSomething(Exchange exchange)
{
      <span class="code-comment">// process the exchange
</span>      exchange.getIn().setBody(<span class="code-quote">"Bye World"</span>);
   }
</pre>
</div></div>

<h4><a name="BeanBinding-@Handler"></a>@Handler</h4>
<p>You can mark a method in your bean with the @Handler annotation to indicate that
this method should be used for <a href="/confluence/display/CAMEL/Bean+Binding" title="Bean
Binding">Bean Binding</a>.<br/>
This has the advantage as you do not have to specify the method name in the Camel route. And
thus you do not run into problems when you rename the method name using an IDE that don't
find all references.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Bar {

    @Handler
    <span class="code-keyword">public</span> <span class="code-object">String</span>
doSomething(<span class="code-object">String</span> body) {
      <span class="code-comment">// process the in body and <span class="code-keyword">return</span>
whatever you want
</span>      <span class="code-keyword">return</span> <span class="code-quote">"Bye
World"</span>;
   }
</pre>
</div></div>


<h3><a name="BeanBinding-Parameterbindingusingmethodoption"></a>Parameter
binding using method option</h3>
<p><b>Available as of Camel 2.9</b></p>

<p>Camel uses the following rules to determine if its a parameter value in the method
option</p>
<ul class="alternate" type="square">
	<li>The value is either <tt>true</tt> or <tt>false</tt> which
denotes a boolean value</li>
	<li>The value is a numeric value such as <tt>123</tt> or <tt>7</tt></li>
	<li>The value is a String enclosed with either single or double quotes</li>
	<li>It can be evaluated using the <a href="/confluence/display/CAMEL/Simple" title="Simple">Simple</a>
language, which means you can use eg body, header.foo and other <a href="/confluence/display/CAMEL/Simple"
title="Simple">Simple</a> tokens.</li>
</ul>


<p>Any other value is consider to be a type declaration instead, see next section about
pin pointing types for overloaded methods.</p>

<p>When invoking a <a href="/confluence/display/CAMEL/Bean" title="Bean">Bean</a>
you can instruct Camel to invoke a specific method by providing the method name. For example
as shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething"</span>)
</pre>
</div></div>

<p>Here we tell Camel to invoke the doSomething method. How the parameters is bound
is handled by Camel. Now suppose the method has 2 parameters, and the 2nd parameter is a boolean,
where we want to pass in a true value, such as the method signature below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> void doSomething(<span class="code-object">String</span>
payload, <span class="code-object">boolean</span> highPriority) {
   ...
}
</pre>
</div></div>

<p>This is now possible in <b>Camel 2.9</b> onwards:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(*, <span class="code-keyword">true</span>)"</span>)
</pre>
</div></div>

<p>In the example above, we defined the first parameter using the wild card symbol *,
which tells Camel to bind this parameter to any type, and let Camel figure this out. The 2nd
parameter has a fixed value of <tt>true</tt>. Instead of the wild card symbol
we can instruct Camel to use the message body as shown:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(body, <span class="code-keyword">true</span>)"</span>)
</pre>
</div></div>

<p>The syntax of the parameters is using the <a href="/confluence/display/CAMEL/Simple"
title="Simple">Simple</a> expression language so we can use ${ } placeholders to
make this more expressive:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(${body}, <span
class="code-keyword">true</span>)"</span>)
</pre>
</div></div>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td>Its a good idea to use ${ } placeholders
in the method option as shown in the example above. This makes it clear to the read, that
this is a <a href="/confluence/display/CAMEL/Simple" title="Simple">Simple</a>
token and the actual value is dynamic computed form the <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a> being routed.</td></tr></table></div>

<p>You can also pass in other fixed values than boolean values. For example to pass
in an String and integer do as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(MyBean.class, <span class="code-quote">"echo('World', 5)"</span>)
</pre>
</div></div>
<p>In the example above, we invoke the echo method with two parameters. The first has
the content 'World' (without the quotes). And the 2nd the value of 5.<br/>
Camel will automatic type convert the values to the parameter types.</p>

<p>Having the power of the <a href="/confluence/display/CAMEL/Simple" title="Simple">Simple</a>
language allows us to bind to message headers and other values such as:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(${body}, ${header.high})"</span>)
</pre>
</div></div>

<p>You can also use the OGNL support of the <a href="/confluence/display/CAMEL/Simple"
title="Simple">Simple</a> expression language. Now suppose the message body is an
object which has a method named <tt>asXml</tt>. To invoke the <tt>asXml</tt>
method we can do as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(${body.asXml}, ${header.high})"</span>)
</pre>
</div></div>

<p>Instead of using <tt>.bean</tt> as shown in the examples above, you may
want to use <tt>.to</tt> instead as shown:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .to(<span class="code-quote">"bean:orderService?method=doSomething(${body.asXml},
${header.high})"</span>)
</pre>
</div></div>


<h3><a name="BeanBinding-Usingtypequalifiertopinpointmethodtousewhenhavingoverloadedmethods"></a>Using
type qualifier to pin-point method to use when having overloaded methods</h3>
<p><b>Available as of Camel 2.8</b></p>

<p>If you have a <a href="/confluence/display/CAMEL/Bean" title="Bean">Bean</a>
which has overloaded methods you can now specify the parameter types in the method name, so
Camel can match the method you intend to use.<br/>
Given the following bean:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>MyBean</b></div><div class="codeContent
panelContent">
<pre class="code-java"><span class="code-keyword">public</span> <span
class="code-keyword">static</span> <span class="code-keyword">final</span>
class MyBean {

    <span class="code-keyword">public</span> <span class="code-object">String</span>
hello(<span class="code-object">String</span> name) {
        <span class="code-keyword">return</span> <span class="code-quote">"Hello
"</span> + name;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
hello(<span class="code-object">String</span> name, @Header(<span class="code-quote">"country"</span>)
<span class="code-object">String</span> country) {
        <span class="code-keyword">return</span> <span class="code-quote">"Hello
"</span> + name + <span class="code-quote">" you are from "</span> + country;
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
times(<span class="code-object">String</span> name, @Header(<span class="code-quote">"times"</span>)
<span class="code-object">int</span> times) {
        StringBuilder sb = <span class="code-keyword">new</span> StringBuilder();
        <span class="code-keyword">for</span> (<span class="code-object">int</span>
i = 0; i &lt; times; i++) {
            sb.append(name);
        }
        <span class="code-keyword">return</span> sb.toString();
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
times(<span class="code-object">byte</span>[] data, @Header(<span class="code-quote">"times"</span>)
<span class="code-object">int</span> times) {
        <span class="code-object">String</span> s = <span class="code-keyword">new</span>
<span class="code-object">String</span>(data);
        StringBuilder sb = <span class="code-keyword">new</span> StringBuilder();
        <span class="code-keyword">for</span> (<span class="code-object">int</span>
i = 0; i &lt; times; i++) {
            sb.append(s);
            <span class="code-keyword">if</span> (i &lt; times - 1) {
                sb.append(<span class="code-quote">","</span>);
            }
        }
        <span class="code-keyword">return</span> sb.toString();
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
times(<span class="code-object">String</span> name, <span class="code-object">int</span>
times, <span class="code-object">char</span> separator) {
        StringBuilder sb = <span class="code-keyword">new</span> StringBuilder();
        <span class="code-keyword">for</span> (<span class="code-object">int</span>
i = 0; i &lt; times; i++) {
            sb.append(name);
            <span class="code-keyword">if</span> (i &lt; times - 1) {
                sb.append(separator);
            }
        }
        <span class="code-keyword">return</span> sb.toString();
    }

}
</pre>
</div></div>

<p>Then the <tt>MyBean</tt> has 2 overloaded methods with the names <tt>hello</tt>
and <tt>times</tt>. So if we want to use the method which has 2 parameters we
can do as follows in the Camel route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Invoke 2 parameter method</b></div><div
class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .bean(MyBean.class, <span class="code-quote">"hello(<span class="code-object">String</span>,<span
class="code-object">String</span>)"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<p>We can also use a <tt>*</tt> as wildcard so we can just say we want to
execute the method with 2 parameters we do</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Invoke 2 parameter method using wildcard</b></div><div
class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .bean(MyBean.class, <span class="code-quote">"hello(*,*)"</span>)
    .to(<span class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<p>By default Camel will match the type name using the simple name, eg any leading package
name will be disregarded. However if you want to match using the FQN then specify the FQN
type and Camel will leverage that. So if you have a <tt>com.foo.MyOrder</tt> and
you want to match against the FQN, and <b>not</b> the simple name "MyOrder" then
do as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   .bean(OrderService.class, <span class="code-quote">"doSomething(com.foo.MyOrder)"</span>)
</pre>
</div></div>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>Camel currently only
supports either specifying parameter binding or type per parameter in the method name option.
You <b>cannot</b> specify both at the same time, such as 
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
doSomething(com.foo.MyOrder ${body}, <span class="code-object">boolean</span>
${header.high})
</pre>
</div></div>
<p>This may change in the future.</p></td></tr></table></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Bean+Binding">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=63026&revisedVersion=38&originalVersion=37">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Bean+Binding?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message