【SpringBoot 采坑记】- FreeMarker
以下以邮件演示说明
1. pom.xml
引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
2. yml
文件:
spring:
freemarker:
cache: false
charset: UTF-8
content-type: text/xml
template-loader-path: classpath:/templates/
suffix: .ftl
3. .ftl
文件
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试模板邮件</title>
</head>
<body>
<table border="1" align="center" width="50%">
<tr>
<th>区域Id</th>
<th>区域名称</th>
<th>区域级别</th>
</tr>
<#list districtModelList as districtModel>
<tr>
<td>${districtModel.districtId}</td>
<td>${districtModel.districtName}</td>
<td>${districtModel.level}</td>
</tr>
</#list>
</table>
</body>
</html>
4..java
文件
-
mail
代码片段
/**
* 发送模板邮件
*
* @param receiver 邮件接收人
* @param subject 邮件主题
* @throws MessagingException
*/
public void sendTemplateMail(String receiver, String subject, Object model) throws MessagingException, IOException, TemplateException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
assembleMailMessage(mimeMessageHelper, receiver, subject);
Template template = configuration.getTemplate("district.ftl", "utf-8");
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
mimeMessageHelper.setText(text, true);
javaMailSender.send(mimeMessage);
}
private void assembleMailMessage(MimeMessageHelper mimeMessageHelper, String receiver, String subject) throws MessagingException {
mimeMessageHelper.setFrom(username);
mimeMessageHelper.setTo(receiver);
mimeMessageHelper.setSentDate(new Date());
mimeMessageHelper.setSubject(subject);
}
-
controller
代码片段
@GetMapping("test/mail/freemarker")
public ApiResponse testMail() throws MessagingException, IOException, TemplateException {
Map<String, Object> map = new HashMap<>(1);
map.put("districtModelList", DataProvider.getDistrictProvince());
mailService.sendTemplateMail("aaa@qq.com", "测试邮件标题", map);
return ApiResponse.success();
}
- 数据代码片段
public static List<DistrictModel> getDistrictProvince() {
List<DistrictModel> districtModelList = new ArrayList<>(23);
districtModelList.add(new DistrictModel("10001", "安徽省", null, 1));
districtModelList.add(new DistrictModel("10002", "福建省", null, 1));
districtModelList.add(new DistrictModel("10003", "甘肃省", null, 1));
districtModelList.add(new DistrictModel("10004", "广东省", null, 1));
districtModelList.add(new DistrictModel("10005", "贵州省", null, 1));
districtModelList.add(new DistrictModel("10006", "海南省", null, 1));
districtModelList.add(new DistrictModel("10007", "河北省", null, 1));
districtModelList.add(new DistrictModel("10008", "河南省", null, 1));
districtModelList.add(new DistrictModel("10009", "黑龙江省", null, 1));
districtModelList.add(new DistrictModel("10010", "湖北省", null, 1));
districtModelList.add(new DistrictModel("10011", "湖南省", null, 1));
districtModelList.add(new DistrictModel("10012", "吉林省", null, 1));
districtModelList.add(new DistrictModel("10013", "江苏省", null, 1));
districtModelList.add(new DistrictModel("10014", "江西省", null, 1));
districtModelList.add(new DistrictModel("10015", "辽宁省", null, 1));
districtModelList.add(new DistrictModel("10016", "青海省", null, 1));
districtModelList.add(new DistrictModel("10017", "山东省", null, 1));
districtModelList.add(new DistrictModel("10018", "山西省", null, 1));
districtModelList.add(new DistrictModel("10019", "陕西省", null, 1));
districtModelList.add(new DistrictModel("10020", "四川省", null, 1));
districtModelList.add(new DistrictModel("10021", "*省", null, 1));
districtModelList.add(new DistrictModel("10022", "云南省", null, 1));
districtModelList.add(new DistrictModel("10023", "浙江省", null, 1));
return districtModelList;
}
-
model
代码片段
@Data
@ApiModel("区域信息")
@AllArgsConstructor
@Accessors(chain = true)
public class DistrictModel {
@ApiModelProperty(value = "区域Id", required = true)
private String districtId;
@ApiModelProperty(value = "区域名称", required = true)
private String districtName;
@ApiModelProperty(value = "父级区域Id")
private String parentDistrictId;
@ApiModelProperty(value = "区域级别", required = true)
private Integer level;
}
5. 效果展示:
注意事项:
-
Map
:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试模板邮件</title>
</head>
<body>
<table border="1" align="center" width="50%">
<tr>
<th>区域Id</th>
<th>区域名称</th>
<th>区域级别</th>
</tr>
<tr>
<td>${districtId}</td>
<td>${districtName}</td>
<td>${level}</td>
</tr>
</table>
</body>
</html>
@GetMapping("test/mail/freemarker")
public ApiResponse testMail() throws MessagingException, IOException, TemplateException {
Map<String, String> map = new HashMap<>(3);
map.put("districtId", "10012");
map.put("districtName", "大连市");
map.put("level", "2");
mailService.sendTemplateMail("aaa@qq.com", "测试邮件标题", map);
return ApiResponse.success();
}
效果图:
2. JavaBean
:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试模板邮件</title>
</head>
<body>
<table border="1" align="center" width="50%">
<tr>
<th>区域Id</th>
<th>区域名称</th>
<th>区域级别</th>
</tr>
<tr>
<td>${districtId}</td>
<td>${districtName}</td>
<td>${level}</td>
</tr>
</table>
</body>
</html>
@GetMapping("test/mail/freemarker")
public ApiResponse testMail() throws MessagingException, IOException, TemplateException {
DistrictModel districtModel = new DistrictModel("10010", "北京市", null, 1);
mailService.sendTemplateMail("aaa@qq.com", "测试邮件标题", districtModel);
return ApiResponse.success();
}
效果图:
-
如果想展示
list
,需要将集合放到map
中,再根据对应key
取出集合,如上所示 -
异常说明
1.freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault...
说明:
map
的key
或者bean
的属性名字对应不上,freemarker
找不到要展示的数据;或者属性的值为null
2.
java.lang.IllegalArgumentException: freemarker.template.DefaultObjectWrapper didn't convert java.util.ArrayList to a TemplateHashModel. Generally, you want to use a Map<String, Object> or a JavaBean as the root-map (aka. data-model) parameter. The Map key-s or JavaBean property names will be the variable names in the template.
说明:
freemarker
需要接收map
或者bean
作为参数,但是你传了一个list
,将list
放入map
中即可
下一篇: python变量的命名规则