【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("[email protected]", "測試郵件標題", 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. 效果展示:

freemarker模板郵件效果展示

注意事項:

  • freemarker只能接受Map鍵值對或者JavaBean作爲參數
    舉例:
  1. 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("[email protected]", "測試郵件標題", map);

        return ApiResponse.success();
    }

效果圖:
Map效果圖
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("[email protected]", "測試郵件標題", districtModel);

        return ApiResponse.success();
    }

效果圖:
JavaBean效果圖

  • 如果想展示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...

    說明mapkey或者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中即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章