使用FreeMarker配置動態模板


FreeMarker動態模板

前言

當我們開發功能時,不僅要考慮當前,也要考慮之后的迭代.
對於郵件正文內容,有時候需要配置HTML格式,所以選擇了FreeMarker

准備工作

  • FreeMarker的依賴
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
  • 其余Spring相關依賴
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

FreeMarker

官方文檔 http://freemarker.foofun.cn/
最簡單的模板通常是普通的HTML文件,當然也可以用來寫word,pdf之類
對於FreeMarker的模板語言,和動態sql有些相似

既然是動態模板,那么是要傳入數據的
http://freemarker.foofun.cn/dgui_datamodel_types.html
常用的傳參類型有List,Map,自定義對象 在上方的官方文檔中你可以查看支持的全部類型

代碼構建

項目結構

image

創建 Configuration 實例

參考官方文檔中步驟 http://freemarker.foofun.cn/pgui_quickstart.html

package com.lizi.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.annotation.PostConstruct;
import java.util.Locale;

/**
 * @author lizi
 * @description FreeMarkerUtil
 * @date 2022/01/01
 */
@Component
@Slf4j
public class FreeMarkerUtil {

    private static Configuration configuration = null;

    @PostConstruct
    public void init() {
        if (null == configuration) {
            // 設置版本號
            configuration = new Configuration(Configuration.VERSION_2_3_23);

            // ”/template“為模板文件來源
            configuration.setClassForTemplateLoading(FreeMarkerTemplateUtils.class, "/template");

            // 設置編碼格式
            configuration.setEncoding(Locale.CHINA, "UTF-8");
        }
    }

    /**
     * @param file template文件路徑
     * @param data 數據
     * @return String
     */
    public static String getResult(String file, Object data) {
        String result = "";
        try {
            // 獲取通用模板
            Template template = configuration.getTemplate(file);

            // 通過模板創建動態數據
            result = FreeMarkerTemplateUtils.processTemplateIntoString(template, data);
        } catch (Exception e) {
            log.error("processTemplateIntoString error : {} ", e.getMessage());
        }
        return result;
    }
}

調用

package com.lizi.controller;

import com.lizi.Entity.Pokemon;
import com.lizi.util.FreeMarkerUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lizi
 * @description FreeMarkerController
 * @date 2022/01/01
 */
@RestController
public class FreeMarkerController {

    @PostMapping("/getTemplate")
    public String getTemplate() {

        // 創建數據模型
        Map<String, Object> dataMap = new HashMap<>(16);

        Map<String, Object> map = new HashMap<>(16);
        map.put("珍珠", "pearl");
        map.put("鑽石", "diamond");

        Pokemon pokemon=new Pokemon();
        pokemon.setName("ground_dragon");
        pokemon.setRace("108,130,95,80,85,102");

        dataMap.put("strong",pokemon);
        dataMap.put("pokemon", map);
        dataMap.put("ground_dragon","108,130,95,80,85,102");
        return FreeMarkerUtil.getResult("template.ftl", dataMap);
    }
}


模板文件

對於模板語言,可以更多的去參考官方文檔,

<html>
<#-- 傳入類型是Map  ${ground_dragon} 表示對Map.get("ground_dragon") -->
<td>${ground_dragon}</td>
<#-- 我傳入的類型是Map 這里pokemon 表示Map.get("pokemon")之后獲取的value 代碼中也是一個Map -->
<#if pokemon?exists>
<#--  list,表示遍歷  -->
    <#list pokemon?keys as key>
        <tr>
            <td>${key}</td>
            <td>${pokemon[key]}</td>
        </tr>
    </#list>
</#if>
<#-- Map.get("strong") 是一個自定義類 訪問屬性可以直接用.的方式獲取 -->
<td>${strong.name}</td>
<td>${strong.race}</td>
</body>
</html>

調用結果

<html>
<td>108,130,95,80,85,102</td>
        <tr>
            <td>鑽石</td>
            <td>diamond</td>
        </tr>
        <tr>
            <td>珍珠</td>
            <td>pearl</td>
        </tr>

<td>ground_dragon</td>
<td>108,130,95,80,85,102</td>
</body>
</html>

Tips

  1. 對於傳入的數據模型,需要用Map做一層包裝,不然會出錯
  2. 如果對象可能不存在,需要做一層判斷,不然會出錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM