结合SpringBoot Mail + Thymeleaf,以Thymeleaf为页面模板,把需要替换的数据交给thymeleaf模板引擎渲染成静态页面,最后作为邮件的text发送。
背景
Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP,Velocity,FreeMaker等, 它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎相比, Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用。
thymeLeaf支持Spring Expression Language语言作为方言,也就是SpEL,在学习JSP时我们对EL表达式都有一定的认识了,SpEL是可以用于Spring中的一种EL表达式。
简而言之,与我们使用过的JSP不同,thymeLeaf是使用html的标签来完成逻辑和数据的传入进行渲染, 而且不用像jsp一样作为一个servlet被编译再生成。即便单独的thymeleaf html文件依旧可以正确打开并有少量(相对)有价值的信息,并且是可以被浏览器直接打开的。
可以说用thymeLeaf完全替代jsp是可行的。何况他的功能更强大。
前后端分离的时代,Thymeleaf模板技术,用来打打辅助可能会有意想不到的收获。
如何使用ThymeLeaf?
spring-boot中不进行任何配置也可以使用,此时使用的是默认配置,需要自定义配置时在properties文件中配置即可。
传统spring项目中,可以通过配置类和xml方式配置模板和视图处理器的Bean
@Slf4j
@SpringBootTest
public class SpringMailTest {
@Value("${spring.mail.username}")
private String sender;
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private TemplateEngine templateEngine;
@Test
public void sendResumeNotify() {
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(sender, "掘金");
helper.setTo("xxx@qq.com");
helper.setSubject("简历投递提醒");
// 定义模板数据
Context context = new Context();
HashMap<String, Object> paramMap = new HashMap<>(16);
paramMap.put("candidate", "xxx");
paramMap.put("sex", 1);
paramMap.put("publisher", "马云");
paramMap.put("jobName", "Java高级开发工程师(saas方向)");
paramMap.put("icon", "https://pic4.zhimg.com/v2-1907eb21be63d35b077e6ed3cbcbfe13_xll.jpg");
paramMap.put("school", "清华大学");
paramMap.put("major", "计算机科学与技术");
paramMap.put("education", "本科");
paramMap.put("status", "已离职");
paramMap.put("expectJob", "软件工程师");
paramMap.put("expectCity", "杭州");
paramMap.put("salaryBegin", 10);
paramMap.put("salaryEnd", 12);
paramMap.put("appendixUrl", "https://wise-job.oss-cn-zhangjiakou.aliyuncs.com/wiseJob/1601035929262.pdf");
paramMap.put("appendixName", "xxx_Java.pdf");
context.setVariables(paramMap);
// 获取thymeleaf模板,填充数据
String emailContent = templateEngine.process("notifyHR", context);
helper.setText(emailContent, true);
// 发送填充好的整个html页面
javaMailSender.send(message);
log.info("简历投递提醒发送成功。");
} catch (Exception e) {
log.error("简历投递提醒发送失败!", e);
}
}
}
spring.mail.host=smtp.qq.com
# 邮箱用户名
spring.mail.username=xxx@qq.com
# 邮箱密码(注意:qq邮箱应该使用独立密码,去qq邮箱设置里面获取)
spring.mail.password=xxx
# 编码格式
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.port=465
spring.mail.properties.mail.smtp.socketFactory.port = 465
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback = false
# java mail发邮件是附件名过长默认会被截断,附件名显示【tcmime.29121.xxx.xxx.bin】,主动设为false可正常显示附件名
spring.mail.properties.mail.mime.splitlongparameters=false
spring.web.resources.static-locations=classpath:/templates/
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.yml</include>
<include>**/*.html</include>
<!--加载静态文件-->
<include>/static/</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
thymeleaf有默认的前缀:classpath:/templates/和后缀:.html,但需要注意如果pom的resources节点有扫描,需加入.html;
知识剖析
Thymeleaf 是一种模板语言。那模板语言或模板引擎是什么?常见的模板语言都包含以下几个概念:数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents)。
数据
数据是信息的表现形式和载体,可以是符号、文字、数字、语音、图像、视频等。数据和信息是不可分离的,数据是信息的表达,信息是数据的内涵。数据本身没有意义,数据只有对实体行为产生影响时才成为信息。
模板
模板,是一个蓝图,即一个与类型无关的类。编译器在使用模板时,会根据模板实参对模板进行实例化,得到一个与类型相关的类。
模板引擎
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
结果文档
一种特定格式的文档,比如用于网站的模板引擎就会生成一个标准的HTML文档。 模板语言用途广泛,常见的用途如下:
- 页面渲染
- 文档生成
- 代码生成
- 所有 “数据+模板=文本” 的应用场景
ThymeLeaf可以实现什么功能?
5种表达式: ${…} : 变量表达式 *{…} : 选择表达式 /#{…} : 消息(i28n)表达式 @{…} : 链接(URL)表达式 ~{…} : 片段表达式
这5个表达式分工不同,但同时也可以互相嵌套。这也是SpEL所支持的,或者说,在Spring项目中使用的这些表达式本身也同时是SpEL
对简单的变量值传递,格式化(日期等),字符串拼接(表达式结果生成的字符串和普通文本字符串),国际化(i18n),转义,迭代(foreach),条件(if/else, switch),SpEL(Spring官方文档Part III 第7节),链接(URL),form(这个就开始有很多不懂得了)等了解。