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

来源:互联网 发布:js form ajax 提交 编辑:程序博客网 时间:2024/06/04 19:02

我们使用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 StringTemplateLoaderextends Objectimplements TemplateLoaderA 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本来就支持这种方式,不需要重新实现方法等其他的。
以上为博客全内容,对以上的内容有疑问或有错误的地方希望大家能指出。