camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Velocity
Date Thu, 27 Oct 2011 18:56: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/Velocity">Velocity</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~muellerc">Christian
Mueller</a>
    </h4>
        <br/>
                         <h4>Changes (1)</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" >|| key || value || <br>| {{exchange}}
| The {{Exchange}} itself. | <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">|
{{exchange.properties}} | The {{Exchange}} properties. | <br></td></tr>
            <tr><td class="diff-unchanged" >| {{headers}} | The headers of the
In message. | <br>| {{camelContext}} | The Camel Context intance. | <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Velocity-Velocity"></a>Velocity</h2>

<p>The <b>velocity:</b> component allows you to process a message using
an <a href="http://velocity.apache.org/" class="external-link" rel="nofollow">Apache
Velocity</a> template. This can be ideal when using <a href="/confluence/display/CAMEL/Templating"
title="Templating">Templating</a> to generate responses for requests.</p>

<p>Maven users will need to add the following dependency to their <tt>pom.xml</tt>
for this component:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
    <span class="code-tag">&lt;groupId&gt;</span>org.apache.camel<span
class="code-tag">&lt;/groupId&gt;</span>
    <span class="code-tag">&lt;artifactId&gt;</span>camel-velocity<span
class="code-tag">&lt;/artifactId&gt;</span>
    <span class="code-tag">&lt;version&gt;</span>x.x.x<span class="code-tag">&lt;/version&gt;</span>
    <span class="code-tag"><span class="code-comment">&lt;!-- use the same
version as your Camel core version --&gt;</span></span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h3><a name="Velocity-URIformat"></a>URI format</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
velocity:templateName[?options]
</pre>
</div></div>

<p>Where <b>templateName</b> is the classpath-local URI of the template
to invoke; or the complete URL of the remote template (eg: <a href="file://folder/myfile.vm"
class="external-link" rel="nofollow">file://folder/myfile.vm</a>).</p>

<p>You can append query options to the URI in the following format, <tt>?option=value&amp;option=value&amp;...</tt></p>

<h3><a name="Velocity-Options"></a>Options</h3>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>loaderCache</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> Velocity based file loader cache. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>contentCache</tt> </td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> New option in Camel 1.4: Cache for the resource content when
it is loaded. By default, it's <tt>false</tt> in Camel 1.x. By default, it's <tt>true</tt>
in Camel 2.x. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>encoding</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> New option in Camel 1.6: Character encoding of the resource
content. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>propertiesFile</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> New option in Camel 2.1: The URI of the properties file which
is used for VelocityEngine initialization. </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="Velocity-MessageHeaders"></a>Message Headers</h3>

<p>The velocity component sets a couple headers on the message (you can't set these
yourself and from Camel 2.1 velocity component will not set these headers which will cause
some side effect on the dynamic template support):</p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Header </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.camel.velocity.resource</tt> </td>
<td class='confluenceTd'> Camel 1.x: The resource as an <tt>org.springframework.core.io.Resource</tt>
object. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>org.apache.camel.velocity.resourceUri</tt>
</td>
<td class='confluenceTd'> Camel 1.x: The <b>templateName</b> as a <tt>String</tt>
object. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>CamelVelocityResource</tt> </td>
<td class='confluenceTd'> Camel 2.0: The resource as an <tt>org.springframework.core.io.Resource</tt>
object. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>CamelVelocityResourceUri</tt> </td>
<td class='confluenceTd'> Camel 2.0: The <b>templateName</b> as a <tt>String</tt>
object. </td>
</tr>
</tbody></table>
</div>
</div>

<p>In Camel 1.4 headers set during the Velocity evaluation are returned to the message
and added as headers. Then its kinda possible to return values from Velocity to the Message.</p>

<p>For example, to set the header value of <tt>fruit</tt> in the Velocity
template <tt>.tm</tt>:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
$in.setHeader('fruit', 'Apple')
</pre>
</div></div>

<p>The <tt>fruit</tt> header is now accessible from the <tt>message.out.headers</tt>.</p>

<h3><a name="Velocity-VelocityContext"></a>Velocity Context</h3>
<p>Camel will provide exchange information in the Velocity context (just a <tt>Map</tt>).
The <tt>Exchange</tt> is transfered as:</p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> key </th>
<th class='confluenceTh'> value </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>exchange</tt> </td>
<td class='confluenceTd'> The <tt>Exchange</tt> itself. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>exchange.properties</tt> </td>
<td class='confluenceTd'> The <tt>Exchange</tt> properties. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>headers</tt> </td>
<td class='confluenceTd'> The headers of the In message. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>camelContext</tt> </td>
<td class='confluenceTd'> The Camel Context intance. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>request</tt> </td>
<td class='confluenceTd'> The In message. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>in</tt> </td>
<td class='confluenceTd'> The In message. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>body</tt> </td>
<td class='confluenceTd'> The In message body. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>out</tt> </td>
<td class='confluenceTd'> The Out message (only for InOut message exchange pattern).
</td>
</tr>
<tr>
<td class='confluenceTd'> <tt>response</tt> </td>
<td class='confluenceTd'> The Out message (only for InOut message exchange pattern).
</td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="Velocity-Hotreloading"></a>Hot reloading</h3>
<p>The Velocity template resource is, by default, hot reloadable for both file and classpath
resources (expanded jar). If you set <tt>contentCache=true</tt>, Camel will only
load the resource once, and thus hot reloading is not possible. This scenario can be used
in production, when the resource never changes.</p>

<h3><a name="Velocity-Dynamictemplates"></a>Dynamic templates</h3>
<p><b>Available as of Camel 2.1</b><br/>
Camel provides two headers by which you can define a different resource location for a template
or the template content itself. If any of these headers is set then Camel uses this over the
endpoint configured resource. This allows you to provide a dynamic template at runtime.</p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Header </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> CamelVelocityResourceUri </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> <b>Camel 2.1:</b> A URI for the template resource
to use instead of the endpoint configured. </td>
</tr>
<tr>
<td class='confluenceTd'> CamelVelocityTemplate </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> <b>Camel 2.1:</b> The template to use instead
of the endpoint configured. </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="Velocity-Samples"></a>Samples</h3>

<p>For example you could use something like</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"activemq:My.Queue"</span>).
  to(<span class="code-quote">"velocity:com/acme/MyResponse.vm"</span>);
</pre>
</div></div>

<p>To use a Velocity template to formulate a response to a message for InOut message
exchanges (where there is a <tt>JMSReplyTo</tt> header).</p>

<p>If you want to use InOnly and consume the message and send it to another destination,
you could use the following route:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"activemq:My.Queue"</span>).
  to(<span class="code-quote">"velocity:com/acme/MyResponse.vm"</span>).
  to(<span class="code-quote">"activemq:Another.Queue"</span>);
</pre>
</div></div>

<p>And to use the content cache, e.g. for use in production, where the <tt>.vm</tt>
template never changes:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"activemq:My.Queue"</span>).
  to(<span class="code-quote">"velocity:com/acme/MyResponse.vm?contentCache=<span
class="code-keyword">true</span>"</span>).
  to(<span class="code-quote">"activemq:Another.Queue"</span>);
</pre>
</div></div>

<p>And a file based resource:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"activemq:My.Queue"</span>).
  to(<span class="code-quote">"velocity:file:<span class="code-comment">//myfolder/MyResponse.vm?contentCache=<span
class="code-keyword">true</span>"</span>).
</span>  to(<span class="code-quote">"activemq:Another.Queue"</span>);
</pre>
</div></div>

<p>In <b>Camel 2.1</b> it's possible to specify what template the component
should use dynamically via a header, so for example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"direct:in"</span>).
  setHeader(<span class="code-quote">"CamelVelocityResourceUri"</span>).constant(<span
class="code-quote">"path/to/my/template.vm"</span>).
  to(<span class="code-quote">"velocity:dummy"</span>);
</pre>
</div></div>

<p>In <b>Camel 2.1</b> it's possible to specify a template directly as a
header the component should use dynamically via a header, so for example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"direct:in"</span>).
  setHeader(<span class="code-quote">"CamelVelocityTemplate"</span>).constant(<span
class="code-quote">"Hi <span class="code-keyword">this</span> is a velocity
template that can <span class="code-keyword">do</span> templating ${body}"</span>).
  to(<span class="code-quote">"velocity:dummy"</span>);
</pre>
</div></div>

<h3><a name="Velocity-TheEmailSample"></a>The Email Sample</h3>
<p>In this sample we want to use Velocity templating for an order confirmation email.
The email template is laid out in Velocity as:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Dear ${headers.lastName}, ${headers.firstName}

Thanks <span class="code-keyword">for</span> the order of ${headers.item}.

Regards Camel Riders Bookstore
${body}
</pre>
</div></div>

<p>And the java code:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">private</span> Exchange
createLetter() {
    Exchange exchange = context.getEndpoint(<span class="code-quote">"direct:a"</span>).createExchange();
    Message msg = exchange.getIn();
    msg.setHeader(<span class="code-quote">"firstName"</span>, <span class="code-quote">"Claus"</span>);
    msg.setHeader(<span class="code-quote">"lastName"</span>, <span class="code-quote">"Ibsen"</span>);
    msg.setHeader(<span class="code-quote">"item"</span>, <span class="code-quote">"Camel
in Action"</span>);
    msg.setBody(<span class="code-quote">"PS: Next beer is on me, James"</span>);
    <span class="code-keyword">return</span> exchange;
}

@Test
<span class="code-keyword">public</span> void testVelocityLetter() <span class="code-keyword">throws</span>
Exception {
    MockEndpoint mock = getMockEndpoint(<span class="code-quote">"mock:result"</span>);
    mock.expectedMessageCount(1);
    mock.expectedBodiesReceived(<span class="code-quote">"Dear Ibsen, Claus\n\nThanks
<span class="code-keyword">for</span> the order of Camel in Action.\n\nRegards
Camel Riders Bookstore\nPS: Next beer is on me, James"</span>);

    template.send(<span class="code-quote">"direct:a"</span>, createLetter());

    mock.assertIsSatisfied();
}

<span class="code-keyword">protected</span> RouteBuilder createRouteBuilder()
<span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            from(<span class="code-quote">"direct:a"</span>).to(<span class="code-quote">"velocity:org/apache/camel/component/velocity/letter.vm"</span>).to(<span
class="code-quote">"mock:result"</span>);
        }
    };
}
</pre>
</div></div>

<h3><a name="Velocity-SeeAlso"></a>See Also</h3>
<ul>
	<li><a href="/confluence/display/CAMEL/Configuring+Camel" title="Configuring Camel">Configuring
Camel</a></li>
	<li><a href="/confluence/display/CAMEL/Component" title="Component">Component</a></li>
	<li><a href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a></li>
	<li><a href="/confluence/display/CAMEL/Getting+Started" title="Getting Started">Getting
Started</a></li>
</ul>

    </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/Velocity">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=67647&revisedVersion=36&originalVersion=35">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Velocity?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message