FreeMarker

发布时间 2023-03-22 21:16:16作者: 大意了没有闪

背景

在开发中经常有发送邮件或者对接第三方服务的需求,这些数据都是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

参考文档:http://freemarker.foofun.cn/index.html