使用Apache Camel / ActiveMQ处理Velocity电子邮件模板中的非字符串

时间:2013-11-20 03:58:23

标签: activemq apache-camel velocity

我继承了一个使用Apache Camel和ActiveMQ发送电子邮件的应用程序,它与Velocity电子邮件模板集成在一起。调用ProducerTemplate.sendBodyAndHeaders()方法将消息正文和标题发送到Queue端点。 Camel上下文XML文件定义了一条路径,该路由首先将消息发送到Velocity模板文件,然后将其结果发送到先前定义的邮件服务器,然后关闭电子邮件。

当我熟悉应用程序时,似乎设置的内容与这些示例的设置并没有太大不同:

http://camel.apache.org/velocity.html http://camel.apache.org/tutorial-example-reportincident-part2.html

问题是这些示例(以及我的应用程序中的当前用法)都具有仅访问简单字符串值的模板。传递给ProducerTemplate.sendBodyAndHeaders()的“body”是一个字符串,其值在模板中作为“$ body”访问。传递给ProducerTemplate.sendBodyAndHeaders()的标头是字符串键映射到字符串值的形式,这些值在模板中被访问为“$ headers.keyName1”,“$ headers.keyName2”等。

一切都很好,但现在我想让我的标题键映射不是字符串,而是列出字符串。 (最好,它实际上是一个POJO的列表,但如果它是一个字符串列表我可以得到。)因此,换句话说,使用给定标题键发送到模板的确切字符串数可能不同于一个调用到下一个,模板将迭代列表以构建电子邮件,因为适用于列表中的许多电子邮件。

我在VTL文档中看到如何编写一个可以以这种方式处理列表的模板...如果我可以将这样的列表传递给模板。但我怎么能在那里得到它?我尝试将Java ArrayList放入Map而不是String,但这似乎不起作用。当我尝试访问$ headers.list时,它只给我文字字符串“$ headers.list”。那么这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

使用org.apache.velocity.VelocityContext类,我们将能够 访问模板中的列表,如下所示

Message message = exchange.getIn();
List<Name> nameList = new ArrayList<Name>()
Name testName = new Name();
testName.setFirstName("testFirstName");
testName.setLastName("testLastName");
nameList.add(testName)

Map<String, Object> model = new HashMap<>();
model.put("nameList", nameList);

VelocityContext velocityContext = new VelocityContext(model);
message.setHeader("camelVelocityContext", velocityContext);

在模板文件中我们应该使用org.apache.velocity.VelocityContext的internalGet方法来访问列表,如下所示

#if(${headers.camelVelocityContext.internalGet("nameList").size()}!=0)
  <table>
    <thead>
        <tr>
            <th class="td-border">FirstName</th>
            <th class="td-border">LastName</th>
        </tr>
    </thead>
    <tbody>
        #foreach($entry in ${headers.camelVelocityContext.internalGet("nameList")} )
        <tr>
            <td class="td-border">$entry.firstName</td>
            <td class="td-border">$entry.lastName</td>
        </tr>
        #end
    </tbody>
  </table>
#end

命名POJO类

public class Name {

private String firstName;

private String lastName;

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

}