freemarker使用String模板进行渲染展示

我们使用freemarker常用写法为配置请求的html等静态页面路径地址方式,从而获取页面渲染数据并进行展示,以下为freemarker官网上的测试例子,详细见官网链接

import freemarker.template.*;
import java.util.*;
import java.io.*;

public class Test {

    public static void main(String[] args) throws Exception {

        /* ------------------------------------------------------------------------ */
        /* You should do this ONLY ONCE in the whole application life-cycle:        */

        /* Create and adjust the configuration singleton */
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
        cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLogTemplateExceptions(false);

        /* ------------------------------------------------------------------------ */
        /* You usually do these for MULTIPLE TIMES in the application life-cycle:   */

        /* Create a data-model */
        Map root = new HashMap();
        root.put("user", "Big Joe");
        Product latest = new Product();
        latest.setUrl("products/greenmouse.html");
        latest.setName("green mouse");
        root.put("latestProduct", latest);

        /* Get the template (uses cache internally) */
        Template temp = cfg.getTemplate("test.ftlh");

        /* Merge data-model with template */
        Writer out = new OutputStreamWriter(System.out);
        temp.process(root, out);
        // Note: Depending on what `out` is, you may need to call `out.close()`.
        // This is usually the case for file output, but not for servlet output.
    }
}

从以上的例子,以下两行代码为我们最常用的方式或者使用springmvc中的modelAndView方式
cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));
latest.setUrl("products/greenmouse.html");

ModelAndView方式

ModelAndView modelAndView = new ModelAndView("/where/you/store/templates/products/greenmouse.html");

让我们试想下有这样一个需求,有一份协议需要展示在pc、wap、app端,内容几乎一样但是需要维护三份因为样式、页面头尾等不一样。带来的后果就是需要技术人员频繁的去修改,而且工作毫无技术含量,修改完成之后还得重新发布上线流程,百害而无一利,协议文件多了之后,那每天啥也不用干别的了,整天都在修改协议。于是乎我们去优化改协议查看过程,优化的流程图为下图。
这里写图片描述

我们把三份协议合成一个,并且交给运营去打理(可以用剩余的时间去深造),由于系统是模块化的后台功能和合同模块不在一个服务器,不推荐使用生成模板文件方式。最优化方案为将协议模板存入数据中,取出模板+模板数据==>渲染展示到前台页面。

首先分析方案的可行性,我选择访问freemarker官网寻求解决方案,官网有freemarker引擎渲染流程图如下:详细见freemarker

这里写图片描述
流程已经明确说明是先渲染数据再进行展示,看到就知道以上的方案是可行的,现在问题是如何将String类型模板渲染数据并输出呢?
从freemarker的api中找到了答案:详见api,freemarker.cache -> StringTemplateLoader

public class StringTemplateLoader
extends Object
implements TemplateLoader
A TemplateLoader that uses a Map with String-s as its source of templates.
In most case the regular way of loading templates from files will be fine. However, there can be situations where you don't want to or can't load a template from a file, e.g. if you have to deploy a single jar for JavaWebStart or if they are contained within a database. A single template can be created manually e.g.

   String templateStr="Hello ${user}";
   Template t = new Template("name", new StringReader(templateStr),
               new Configuration());

If, however, you want to create templates from strings which import other templates this method doesn't work.

In that case you can create a StringTemplateLoader and add each template to it:

   StringTemplateLoader stringLoader = new StringTemplateLoader();
   stringLoader.putTemplate("greetTemplate", "<#macro greet>Hello</#macro>");
   stringLoader.putTemplate("myTemplate", "<#include \"greetTemplate\"><@greet/> World!");

Then you tell your Configuration object to use it:

   cfg.setTemplateLoader(stringLoader);

翻译下以上内容大致为freemarker适用于使用String类型作为模板源。详细用法见以下实战代码:

        StringWriter writer = new StringWriter();
        String content = "你的名字${name}";

        Configuration configuration = new Configuration();  
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        stringLoader.putTemplate("contract", content);
        configuration.setTemplateLoader(stringLoader);

        Template template = configuration.getTemplate("contract","utf-8");  
        Map<String,Object> root = new HashMap<String,Object>();    
        root.put("name", "郭啸天");  
        try {  
            template.process(root, writer);  
            System.out.println(writer.toString());    
            response.getWriter().print(writer.toString());
        } catch (TemplateException e) {  
                e.printStackTrace();  
        }

其实实现起来还是蛮简单的,毕竟freemarker本来就支持这种方式,不需要重新实现方法等其他的。
以上为博客全内容,对以上的内容有疑问或有错误的地方希望大家能指出。

猜你喜欢

转载自blog.csdn.net/fu250/article/details/73223580