2020 年 11 月 1 日

IT Skills 波林

Polin WEI – 資訊工作者的技術手札

Spring Boot 使用 Freemarker 開發 Java Tag 客製標籤

2 min read
新光三越

Spring Boot 使用 Freemarker 開發 Java Tag 客製標籤

Java Taglib 自訂標籤簡介 說明了Java Tag 的基本原理,文章中 Java Customize Tag – 客製 Java Tag 標籤程式範例 也展示一支範例程式,而 Spring Boot 使用 Freemarker 模板來快速建立客製化的標籤 (tag) 是非常簡單的事. 作下列幾個步驟即可。

  1. 設定一個 Freemarker Template
  2. 建立 tag 的 class
  3. 建立標籤文件 tld
  4. 註冊 tag
  5. 在 FTL or JSP 中使用

 

  • 設定一個 Freemarker Template : ftlTagSample.ftl

建立一個簡單的 Freemarker 檔案 /src/main/resources/templates/demo/ftlTagSample.ftl 來作測試,主要是依傳入 userName & userTitle 的參數後,依傳入的參數顯示在相同的 HTML 網頁上。

<body>    

    <div><h2>WELCOME,${userName}</h2></div>

    <div>Title:${userTitle}</div>

</body>

 

  • 建立 tag 的 class : FtlTemplateTag.java
public class FtlTemplateTag extends TagSupport {

  private static final long serialVersionUID = 1L;
  
  private String fileName = null;
  private String paramsStr = null;
  private String columnsStr = null;
  private ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    
  public void setFileName(String fileName) {
    this.fileName = fileName;
  }    
  public void setParamsStr(String paramsStr) {
    this.paramsStr = paramsStr;
  }
  public void setColumnsStr(String columnsStr) {
    this.columnsStr = columnsStr;
  }
  /**
   * JSON 字串轉換成 MAP
   * @return
   */
  private Map setParams() {
    Gson gson = new Gson();
    return gson.fromJson(paramsStr, new TypeToken>() {
    }.getType());
  }
  
  private Map setColumns(){
    Locale locale = LocaleContextHolder.getLocale();
    
    messageSource.setBasenames("i18n/messages");
    
    Gson gson = new Gson();
    Map columns = gson.fromJson(columnsStr, new TypeToken>() {}.getType() );
    
    //轉換多語系
    Map dataModel = new LinkedHashMap();
    columns.forEach( (k,v)-> dataModel.put(k, messageSource.getMessage(v, null, v, locale)) );
      
    return dataModel;
  }
  
  
  @Override
  public int doStartTag() throws JspException {
    JspWriter out = pageContext.getOut();
    
    Configuration conf = new Configuration();
    conf.setClassForTemplateLoading(this.getClass(), "/templates/");
    conf.setDefaultEncoding("UTF-8");
    
    try {
      Template  tl = conf.getTemplate(fileName);
      Map dataModel = new HashMap();
      dataModel.putAll(this.setParams());
      dataModel.put("columns", this.setColumns());
      

      tl.process(dataModel, out);
      
    } catch (Exception e) {
      e.printStackTrace();
    }       
    return Tag.SKIP_BODY;
  }
}

 

建立標籤文件 tld : /src/main/resources/static/tags/polinwei.tld

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">
    <description>Polin WEI Tag Library</description>

    <tlib-version>1.0</tlib-version>
    <short-name>pw</short-name>
    <uri>/polinwei/tags</uri>

    <tag>
        <description>Get the file name of freemarker template</description>
        <name>FtlSampleTemplate</name>
        <tag-class>com.spring.jwt.tablibs.FtlTemplateTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <description> Freemarker Template 的檔案</description>
            <name>fileName</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>parmsStr</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>columnsStr</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

 

註冊 tag : polinwei.tld

@Configuration
public class MvcConfig implements WebMvcConfigurer {
   @Autowired
   FreeMarkerConfigurer freeMarkerConfigurer;    
    /**
     *  
     *    加入 spring-security-taglibs 對 FreeMarker 的支援
     */
    @PostConstruct    
    public void freeMarkerConfigurer() {
        List tlds = new ArrayList();        
        tlds.add("/static/tags/polinwei.tld");
        TaglibFactory taglibFactory = freeMarkerConfigurer.getTaglibFactory();
        taglibFactory.setClasspathTlds(tlds);
        if(taglibFactory.getObjectWrapper() == null) {
            taglibFactory.setObjectWrapper(freeMarkerConfigurer.getConfiguration().getObjectWrapper());
        }
    }

}

 

在 FTL 中使用客製的 taglib :

<#import "/spring.ftl" as spring/>
<#assign security=JspTaglibs["http://www.springframework.org/security/tags"] />
<#assign pw=JspTaglibs["/polinwei/tags"] />

<p>測試從模版中讀取信息</p>
<@pw.FtlSampleTemplate fileName="demo/ftlTagSample.ftl" 
    paramsStr="{'Avatar':'polin.jpg','userName':'Polin WEI','userTitle':'MIS'}" />

 

Copyright © All rights reserved. | Newsphere by AF themes.