camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Freemarker
Date Tue, 22 Sep 2009 06:21:02 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Freemarker">Freemarker</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="Freemarker-Freemarker"></a>Freemarker</h2>
<p><b>Available as of Camel 1.6</b></p>

<p>The <b>freemarker:</b> component allows you to process a message using
a <a href="http://freemarker.org/" rel="nofollow">Freemarker</a> template. This
can be ideal when using <a href="/confluence/display/CAMEL/Templating" title="Templating">Templating</a>
to generate responses for requests.</p>

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

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
freemarker: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.ftl"
rel="nofollow">file://folder/myfile.ftl</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="Freemarker-Options"></a>Options</h3>

<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>contentCache</tt> </td>
<td class='confluenceTd'> <tt>true</tt> </td>
<td class='confluenceTd'> Cache for the resource content when its loaded. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>encoding</tt> </td>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> Character encoding of the resource content. </td>
</tr>
</tbody></table>

<h3><a name="Freemarker-Headers"></a>Headers</h3>
<p>Camel will store a reference to the resource in the message header in the key <tt>org.apache.camel.freemarker.resource</tt>.
The Resource is an <tt>org.springframework.core.io.Resource</tt> object. And the
key <tt>org.apache.camel.freemarker.resourceUri</tt> holds the <b>templateName</b>
as a String object.</p>

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

<p>An example: Set the header value of <tt>fruit</tt> in the Freemarker
template:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
${request.setHeader('fruit', 'Apple')}
</pre>
</div></div>

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

<h3><a name="Freemarker-FreemarkerContext"></a>Freemarker Context</h3>
<p>Camel will provide exchange information in the Freemarker context (just a <tt>Map</tt>).
The <tt>Exchange</tt> is transfered as:</p>
<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 Exchange itself. </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. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>request</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>response</tt> </td>
<td class='confluenceTd'> The Out message (only for InOut message exchange pattern).
</td>
</tr>
</tbody></table>

<h3><a name="Freemarker-Hotreloading"></a>Hot reloading</h3>
<p>The Freemarker template resource is by default <b>not</b> hot reloadable
for both file and classpath resources (expanded jar). If you set <tt>contentCache=false</tt>,
then Camel will not cache the resource and hot reloading is thus enabled. This scenario can
be used in development.</p>

<h3><a name="Freemarker-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>

<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'> CamelFreemarkerResourceUri </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'> CamelFreemarkerTemplate </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>


<h3><a name="Freemarker-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">"freemarker:com/acme/MyResponse.ftl"</span>);
</pre>
</div></div>

<p>To use a Freemarker template to formulate a response for 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:</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">"freemarker:com/acme/MyResponse.ftl"</span>).
  to(<span class="code-quote">"activemq:Another.Queue"</span>);
</pre>
</div></div>

<p>And to disable the content cache, e.g. for development usage where the <tt>.ftl</tt>
template should be hot reloaded:</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">"freemarker:com/acme/MyResponse.ftl?contentCache=<span
class="code-keyword">false</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">"freemarker:file:<span class="code-comment">//myfolder/MyResponse.ftl?contentCache=<span
class="code-keyword">false</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">"CamelFreemarkerResourceUri"</span>).constant(<span
class="code-quote">"path/to/my/template.ftl"</span>).
  to(<span class="code-quote">"freemarker:dummy"</span>);
</pre>
</div></div>

<h3><a name="Freemarker-TheEmailSample"></a>The Email Sample</h3>
<p>In this sample we want to use Freemarker templating for an order confirmation email.
The email template is laid out in Freemarker 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 testFreemarkerLetter() <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">"freemarker:org/apache/camel/component/freemarker/letter.ftl"</span>).to(<span
class="code-quote">"mock:result"</span>);
        }
    };
}
</pre>
</div></div>

<h3><a name="Freemarker-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="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Freemarker">View Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=108293&revisedVersion=6&originalVersion=5">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Freemarker?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message