背景
在开发中经常有发送邮件或者对接第三方服务的需求,这些数据都是html或xml格式的,特别是发送邮件时,css必须是行内样式才生效,这些html+css字符串定义在java字符串变量中很不优雅,使用模板引擎正好能解决这个问题,看官方介绍也很符合要求。
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
配置
文档建议使用单例实例配置,所以直接交由spring管理。
参考:http://freemarker.foofun.cn/pgui_quickstart_createconfiguration.html
@Configuration
public class FreemarkerConfig {
@Bean("freemarkerConfiguration")
public freemarker.template.Configuration getFreemarkerConfiguration(){
// 版本根据实际引入的版本进行选择
freemarker.template.Configuration cfg = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_30);
try {
File file = new DefaultResourceLoader().getResource("classpath:/templates/").getFile();
cfg.setDirectoryForTemplateLoading(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
cfg.setDefaultEncoding(StandardCharsets.UTF_8.toString());
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
return cfg;
}
}
测试模板
<table>
<tr>
<th>名称</th>
<th>年龄</th>
<th>数量</th>
<th>日期</th>
</tr>
<#list users as user>
<tr>
<td>${user.name}</td>
<td>${user.age!"22"}</td>
<td>${user.total?string("0.00")}</td>
<td>${user.date?string("yyyy-MM-dd HH:mm:ss")}</td>
</tr>
</#list>
</table>
实体类
实体类不能是内部类,否则在模板中找不到对象
@Data
@AllArgsConstructor
public class User {
private String name;
private Integer total;
private Date date;
}
调用
@Slf4j
@SpringBootTest
public class FreemarkerTest {
@Resource(name = "freemarkerConfiguration")
private Configuration cfg;
@Test
void sendMail() throws Exception {
Template template = cfg.getTemplate("mail.ftl");
List<User> users = Arrays.asList(new User("客户1", 10, new Date()), new User("客户2", 100, new Date()));
Map<String, Object> map = new HashMap<>();
map.put("users", users);
String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
System.out.println(content);
}
}
输出:
<table>
<tr>
<th>名称</th>
<th>年龄</th>
<th>数量</th>
<th>日期</th>
</tr>
<tr>
<td>客户1</td>
<td>22</td>
<td>10.00</td>
<td>2023-03-22 16:56:31</td>
</tr>
<tr>
<td>客户2</td>
<td>22</td>
<td>100.00</td>
<td>2023-03-22 16:56:31</td>
</tr>
</table>
其它
如果从其它地方加载模板,可以参考freemarker.cache.TemplateLoader
类,参考文档:http://freemarker.foofun.cn/pgui_config_templateloading.html