19.3.1 使用 Velocity 构建 Email 消息

Apache Velocity 是由 Apache 提供的通用模板引擎。Velocity 有挺长的历史了,并且已经应用于各种任务中,包括代码生成以及代替 JSP。它还能用于格式化富文本 Email 消息,也就是我们在这里的用法。

为了使用 Velocity 对 Email 进行布局,我们需要将 VelocityEngine 装配到 SpitterEmailServiceImpl 中。Spring 提供了一个名为 VelocityEngineFactoryBean 的工厂 bean,它能够在 Spring 应用上下文中很便利地生成 VelocityEngine。VelocityEngineFactoryBean 的声明如下:

@Bean
public VelocityEngineFactoryBean velocityEngine() {
  VelocityEngineFactoryBean velocityEngine = new VelocityEngineFactoryBean();
  
  Properties props = new Properties();
  props.setProperty("resource.loader", "class");
  props.setProperty("class.resource.loader.class", ClasspathResourceLoader.class.getName());
  
  velocityEngine.setVelocityProperties(props);
  return velocityEngine;
}

VelocityEngineFactoryBean 唯一要设置的属性是 velocityProperties。在本例中,我们将其配置为从类路径下加载 Velocity 模板(关于配置 Velocity 的更多细节,请查阅 Velocity 文档)。

现在,我们可以将 Velocity 引擎装配到 SpitterEmailServiceImpl 中。因为 SpitterEmailServiceImpl 是使用组件扫描实现自动注册的,我们可以使用 @Autowired 来自动装配 velocityEngine 属性:

@Autowired
VelocityEngine velocityEngine;

现在,velocityEngine 属性可用了,我们可以使用它将 Velocity 模板转换为 String,并作为 Email 文本进行发送。为了帮助我们完成这一点,Spring 自带了 VelocityEngineUtils 来简化将 Velocity 模板与模型数据合并成 String 的工作。以下是我们可能的使用方式:

Map<String, String> model = new HashMap<String, String>();
model.put("spitterName", spitterName);
model.put("spitterText", spitterText);
String mailText = VelocityEngineUtils.mergeTemplateIntoString(
  velocityEngine, "emailTemplate.vm", model);

为了给处理模板做准备,我们首先创建了一个 Map 用来保存模板使用的模型数据。在前面字符串拼接的代码中,我们需要 Spitter 的全名及其 Spittle 的文本,这里也是一样。为了产生合并后的 Email 文本,我们只需调用 VelocityEngineUtils 的 mergeTemplateIntoString() 方法并将 Velocity 引擎、模板路径(相对于类路径根)以及模型 Map 传递进去。

在 Java 代码中剩下的事情就是得到合并后的 Email 文本,并将其传递给 helper 的 setText() 方法:

helper.setText(emailText, true);

模板位于类路径的根目录下,是一个名为 emailTemplate.vm 的文件,它看起来可能是这样的:

<html>
<body>
  <img src='cid:spitterLogo'>
  <h4>${spitterName} says...</h4>
  <i>${spittleText}</i>
</body>
</html>

你可以看到,模板文件比前面的字符串拼接版本读起来容易多了。因此,它也更容易维护和编辑。图 19.2 给出了这种类型 Email 的一个示例。

在看到图 19.2 的效果后,我觉得有很多地方可以对模板进行优化从而使得 Email 看起来更漂亮。但是,我将它作为给读者的练习。

Velocity 作为模板引擎已经存在好多年了,并且适用于很多种任务。但是,如第 6 章所示,一种新的模板方案正在变得日益流行。接下来,我们看一下如何使用 Thymeleaf 来构建 Spittle Email 消息。

Last updated