FreeMarker动态模板

前言

当我们开发功能时,不仅要考虑当前,也要考虑之后的迭代.

对于邮件正文内容,有时候需要配置HTML格式,所以选择了FreeMarker

准备工作

  • FreeMarker的依赖
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-freemarker</artifactId>
  4. </dependency>
  • 其余Spring相关依赖
  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <optional>true</optional>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>

FreeMarker

官方文档 http://freemarker.foofun.cn/

最简单的模板通常是普通的HTML文件,当然也可以用来写word,pdf之类

对于FreeMarker的模板语言,和动态sql有些相似

既然是动态模板,那么是要传入数据的

http://freemarker.foofun.cn/dgui_datamodel_types.html

常用的传参类型有List,Map,自定义对象 在上方的官方文档中你可以查看支持的全部类型

代码构建

项目结构

创建 Configuration 实例

参考官方文档中步骤 http://freemarker.foofun.cn/pgui_quickstart.html

  1. package com.lizi.util;
  2. import freemarker.template.Configuration;
  3. import freemarker.template.Template;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
  7. import javax.annotation.PostConstruct;
  8. import java.util.Locale;
  9. /**
  10. * @author lizi
  11. * @description FreeMarkerUtil
  12. * @date 2022/01/01
  13. */
  14. @Component
  15. @Slf4j
  16. public class FreeMarkerUtil {
  17. private static Configuration configuration = null;
  18. @PostConstruct
  19. public void init() {
  20. if (null == configuration) {
  21. // 设置版本号
  22. configuration = new Configuration(Configuration.VERSION_2_3_23);
  23. // ”/template“为模板文件来源
  24. configuration.setClassForTemplateLoading(FreeMarkerTemplateUtils.class, "/template");
  25. // 设置编码格式
  26. configuration.setEncoding(Locale.CHINA, "UTF-8");
  27. }
  28. }
  29. /**
  30. * @param file template文件路径
  31. * @param data 数据
  32. * @return String
  33. */
  34. public static String getResult(String file, Object data) {
  35. String result = "";
  36. try {
  37. // 获取通用模板
  38. Template template = configuration.getTemplate(file);
  39. // 通过模板创建动态数据
  40. result = FreeMarkerTemplateUtils.processTemplateIntoString(template, data);
  41. } catch (Exception e) {
  42. log.error("processTemplateIntoString error : {} ", e.getMessage());
  43. }
  44. return result;
  45. }
  46. }

调用

  1. package com.lizi.controller;
  2. import com.lizi.Entity.Pokemon;
  3. import com.lizi.util.FreeMarkerUtil;
  4. import org.springframework.web.bind.annotation.PostMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. /**
  9. * @author lizi
  10. * @description FreeMarkerController
  11. * @date 2022/01/01
  12. */
  13. @RestController
  14. public class FreeMarkerController {
  15. @PostMapping("/getTemplate")
  16. public String getTemplate() {
  17. // 创建数据模型
  18. Map<String, Object> dataMap = new HashMap<>(16);
  19. Map<String, Object> map = new HashMap<>(16);
  20. map.put("珍珠", "pearl");
  21. map.put("钻石", "diamond");
  22. Pokemon pokemon=new Pokemon();
  23. pokemon.setName("ground_dragon");
  24. pokemon.setRace("108,130,95,80,85,102");
  25. dataMap.put("strong",pokemon);
  26. dataMap.put("pokemon", map);
  27. dataMap.put("ground_dragon","108,130,95,80,85,102");
  28. return FreeMarkerUtil.getResult("template.ftl", dataMap);
  29. }
  30. }

模板文件

对于模板语言,可以更多的去参考官方文档,

  1. <html>
  2. <#-- 传入类型是Map ${ground_dragon} 表示对Map.get("ground_dragon") -->
  3. <td>${ground_dragon}</td>
  4. <#-- 我传入的类型是Map 这里pokemon 表示Map.get("pokemon")之后获取的value 代码中也是一个Map -->
  5. <#if pokemon?exists>
  6. <#-- list,表示遍历 -->
  7. <#list pokemon?keys as key>
  8. <tr>
  9. <td>${key}</td>
  10. <td>${pokemon[key]}</td>
  11. </tr>
  12. </#list>
  13. </#if>
  14. <#-- Map.get("strong") 是一个自定义类 访问属性可以直接用.的方式获取 -->
  15. <td>${strong.name}</td>
  16. <td>${strong.race}</td>
  17. </body>
  18. </html>

调用结果

  1. <html>
  2. <td>108,130,95,80,85,102</td>
  3. <tr>
  4. <td>钻石</td>
  5. <td>diamond</td>
  6. </tr>
  7. <tr>
  8. <td>珍珠</td>
  9. <td>pearl</td>
  10. </tr>
  11. <td>ground_dragon</td>
  12. <td>108,130,95,80,85,102</td>
  13. </body>
  14. </html>

Tips

  1. 对于传入的数据模型,需要用Map做一层包装,不然会出错
  2. 如果对象可能不存在,需要做一层判断,不然会出错

使用FreeMarker配置动态模板的更多相关文章

  1. vert.x学习(六),动态模板与静态文件的结合

    这篇学习在动态模板里面引入css,把动态模板与静态文件结合起来使用. 编写DynamicReference.java package com.javafm.vertx.helloworld; impo ...

  2. SpringBoot下配置FreeMarker配置远程模版

    需求产生原因 要求在同一个接口中,根据不同的参数,返回不同的视图结果 所有的视图中的数据基本一致 要求页面能静态化,优化SEO 例如:A接口返回客户的信息 客户A在调用接口时,返回其个性化定制的页面A ...

  3. 如何通过Spring Boot配置动态数据源访问多个数据库

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

  4. 使用freemarker生成xml模板

    今天在java交流群里有个人问我如何用freemarker生成xml模板文件,可以手动配置参数,于是我到网上百度了一下.发现有一位同行的博文写的很nice,于是我就照着他的代码敲了一遍,最后实现了,本 ...

  5. 迷你MVVM框架 avalonjs 沉思录 第3节 动态模板

    模板的发明是编程史上的一大里程碑,让我们摆脱了烦锁且易出错的字符串拼接,维护性大大提高. 都在JSP,ASP时代,人们已经学会使用include等语句,将多个页面片断拼接成一个页面. 此外,为了将数据 ...

  6. FreeMarker之根据模板生成Java代码

    FreeMarker根据模板生成Java代码,光这句话,大家想必也知道它的应用了,比如流行的DRY原则,该原则的意思,可简单概述为"不要写重复的代码". 比如Java中三层架构,数 ...

  7. spark写入ES(动态模板)

    使用es-hadoop插件,主要使用elasticsearch-spark-20_2.11-6.2.x.jar 官网:https://www.elastic.co/guide/en/elasticse ...

  8. SpringBoot整合MyBatisPlus配置动态数据源

    目录 SpringBoot整合MyBatisPlus配置动态数据源 SpringBoot整合MyBatisPlus配置动态数据源 推文:2018开源中国最受欢迎的中国软件MyBatis-Plus My ...

  9. Logstash动态模板映射收集Nginx的Json格式日志

    Logstash传输给ES的数据会自动映射为5索引,5备份,字段都为text的的索引.这样基本上无法进行数据分析.所以必须将Logstash的数据按照既定的格式存储在ES中,这时候就要使用到ES模板技 ...

随机推荐

  1. 记一次Linux server偶发CPU飙升问题的跟进与解决

    背景 进入6月后,随着一个主要功能版本api的上线,服务端的QPS翻了一倍,平时服务器的CPU使用稳定在30%上下,高峰期则在60%上下,但是偶尔会有单台机器出现持续数分钟突然飙到90%以上,导致大量 ...

  2. 转:windows下定时执行备份数据库

    上一篇写了linux下定时任务,这一篇转发一个windows下定时备份数据库. 第一种:新建批处理文件 backup.dat,里面输入以下 net stop mysql xcopy "C:\ ...

  3. python的嵌入式开发

    今天晚上注定我要玩一夜这个东西,太爽了,给力! 烧写固件成功, http://blog.csdn.net/Lingdongtianxia/article/details/78248888 要点总结:如 ...

  4. 中国联通改造 Apache DolphinScheduler 资源中心,实现计费环境跨集群调用与数据脚本一站式访问

    截止2022年,中国联通用户规模达到4.6亿,占据了全中国人口的30%,随着5G的推广普及,运营商IT系统普遍面临着海量用户.海量话单.多样化业务.组网模式等一系列变革的冲击. 当前,联通每天处理话单 ...

  5. Apache SeaTunnel (Incubating) 2.1.0 发布,内核重构、全面支持 Flink

    2021 年 12 月 9 日,SeaTunnel (原名 Waterdrop) 成功加入 Apache 孵化器,进入孵化器后,SeaTunnel 社区花费了大量时间来梳理整个项目的外部依赖以确保整个 ...

  6. python包合集-cffi

    一.cffi cffi是连接Python与c的桥梁,可实现在Python中调用c文件.cffi为c语言的外部接口,在Python中使用该接口可以实现在Python中使用外部c文件的数据结构及函数. 二 ...

  7. CF280D k-Maximum Subsequence Sum(线段树)

    在做这题时我一开始把\(tag\)写入了结构体 #include <iostream> #include <cstdio> #include <cstring> # ...

  8. Spring 01: Spring配置 + IOC控制反转 + Setter注入

    简介 Spring框架是一个容器,是整合其他框架的框架 他的核心是IOC(控制反转)和AOP(面向切面编程),由20多个模块构成,在很多领域都提供了优秀的问题解决方案 特点 轻量级:由20多个模块构成 ...

  9. java数组---初始化

    public class ArrayDemo { public static void main(String[] args) { int[] a={1,2,3,4,5,6,7,8,9}; //静态初 ...

  10. 简易的AutoPlayCarousel 轮播控件

    原理是使用StackPanel 的margin属性的偏移来实现轮播的效果 废话不多说直接上代码 AutoPlayCarousel核心代码 [ContentProperty(nameof(Childre ...