# 19.3.1　使用 Velocity 构建 Email 消息

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

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

```java
@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 属性：

```java
@Autowired
VelocityEngine velocityEngine;
```

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

```java
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() 方法：

```java
helper.setText(emailText, true);
```

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

```markup
<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 消息。

![图 19.2 Velocity 模板和嵌入的图片能够装扮原本单调乏味的 Email](https://3784153818-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LmcjU5gG__lBrRbUxBO%2F-Lnz3kIUCGekaDIxRlrD%2F-Lnz7-hGb30mE9DJKMz9%2F19.2%20velocity%20%E6%A8%A1%E6%9D%BF.jpg?alt=media\&token=7ffa890e-1fe5-491c-91ed-ac53986c8391)
