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 14:59: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 (2)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <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;">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></td></tr>
            <tr><td class="diff-unchanged" >h4. Parameter binding <br>When
a method have been chosen to be invoked Camel will bind to the parameters of the method. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <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></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>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>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>   .bean(OrderService.class, &quot;doSomething&quot;)
<br>{code} <br> <br>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: <br>{code} <br>public void doSomething(String payload, boolean
highPriority) { <br>   ... <br>} <br>{code} <br> <br>This is
now possible in *Camel 2.9* onwards: <br>{code} <br>   .bean(OrderService.class,
&quot;doSomething(*, true)&quot;) <br>{code} <br> <br>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 {{true}}. Instead of the wild card symbol we can instruct Camel to use the message body
as shown: <br>{code} <br>   .bean(OrderService.class, &quot;doSomething(body,
true)&quot;) <br>{code} <br> <br>The syntax of the parameters is using
the [Simple] expression language so we can use ${ } placeholders to make this more expressive:
<br>{code} <br>   .bean(OrderService.class, &quot;doSomething(${body}, true)&quot;)
<br>{code} <br> <br>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>
  .bean(MyBean.class, &quot;echo(&#39;World&#39;, 5)&quot;) <br>{code}
<br>In the example above, we invoke the echo method with two parameters. The first has
the content &#39;World&#39; (without the quotes). And the 2nd the value of 5. <br>Camel
will automatic type convert the values to the parameter types. <br> <br>Having
the power of the [Simple] language allows us to bind to message headers and other values such
as: <br>{code} <br>   .bean(OrderService.class, &quot;doSomething(${body},
${header.high})&quot;) <br>{code} <br> <br>You can also use the OGNL
support of the [Simple] expression language. Now suppose the message body is an object which
has a method named {{asXml}}. To invoke the {{asXml}} method we can do as follows: <br>{code}
<br>   .bean(OrderService.class, &quot;doSomething(${body.asXml}, ${header.high})&quot;)
<br>{code} <br> <br>Instead of using {{.bean}} as shown in the examples
above, you may want to use {{.to}} instead as shown: <br>{code} <br>   .to(&quot;bean:orderService?method=doSomething(${body.asXml},
${header.high})&quot;) <br>{code} <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h3><a name="BeanBinding-BeanBinding"></a>Bean Binding</h3>

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

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

<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> (<b>org.apache.camel.MethodName</b>
in Camel 1.x) then that method is invoked, converting the body to whatever the argument is
to the method. 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.</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></li>
	<li><b>Camel 2.0:</b> 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>


<h4><a name="BeanBinding-Parameterbinding"></a>Parameter binding</h4>
<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><b>Camel 2.0:</b> <tt>org.apache.camel.CamelContext</tt></li>
	<li><tt>org.apache.camel.TypeConverter</tt></li>
	<li><b>Camel 2.0:</b> <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. See next section for details.</p>

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

<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><b>Available as of Camel 2.0</b></p>

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


<h4><a name="BeanBinding-POJOconsuming"></a>POJO consuming</h4>
<p>For example you could use <a href="/confluence/display/CAMEL/POJO+Consuming" title="POJO
Consuming">POJO Consuming</a> to write a bean like this</p>
<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><b>@Consume
requires camel-spring</b><br />Using the <tt>@Consume</tt> annotations
requires <b>camel-spring</b> that uses the <tt>org.apache.camel.spring.CamelBeanPostProcessor</tt>
to perform the setup for this consumer and the needed bean bindings.</td></tr></table></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><b>@MessageDriven is @deprecated</b><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.</td></tr></table></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Foo {

    @Consume(uri = <span class="code-quote">"activemq:my.queue"</span>)
    <span class="code-keyword">public</span> void doSomething(<span class="code-object">String</span>
body) {
		<span class="code-comment">// process the inbound message here
</span>    }

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

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


<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>The current implementation
for choosing method using type qualifiers only compares the type names. It does <b>not</b>
check any <tt>instanceof</tt> checks or the likes. The type name must match exactly,
as its using a string equals comparison.</td></tr></table></div>


<h3><a name="BeanBinding-Specifyingparametervaluesinmethodnamesyntax"></a>Specifying
parameter values in method name syntax</h3>
<p><b>Available as of Camel 2.9</b></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>

<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>
    </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=36&originalVersion=35">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