zoukankan      html  css  js  c++  java
  • Freemarker使用入门

    一、概述:
    FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写
    Template + data_model = output
    FreeMarker也是与Web容器无关的,也就是FreeMarker并不一定需要运行在Web容器中:FreeMarker同样可以应用于非Web应用程序环境.而且,FreeMarker并不是只能生成HTML页面,它也可以生成各种文本,如XML,RTF,Java源代码等.


    二、前期准备:
    下载jar包:freemarker-2.3.16.jar

    三、HelloWorld:
    A、调用代码:

    /**
         * 本示例未依赖WEB环境,仅简单按照模板生成文件
         * Freemarker指令也非本文讨论内容
         * Template + data_model = output
         */
        public void testFreemarker() {
            
            try {
                
                String dir = "D:/TEST/freemarker/test"; //Freemarker模板存放的路径,可随意设置
                  
                Configuration cfg = new Configuration(); //Freemarker的起始类,要使用Freemarker功能必须通过该类
                  
                cfg.setDirectoryForTemplateLoading(new File(dir));//freemarker从什么地方加载模板文件  
                
                cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);//忽略异常  
                
                Template template = cfg.getTemplate("test01.ftl","UTF-8"); //加载模板 ,这里即从D:/TEST/freemarker/test下加载名称为test01.ftl的模板,编码可以不指定
                  
                //定义数据 ,这里将一个List放到了Map中,该Map即为所谓的data_model
                Map<String, List<String>> root = new HashMap<String, List<String>>();  
                List<String> list = new ArrayList<String>();  
                for(int i=0; i<10; i++){  
                    list.add("listvalue"+i);  
                }  
                root.put("list", list);  
                  
                //定义输出 ,这里只要指定输出即可,在web环境下,可以指定为response.getWriter();此处的做法是生成一个静态文件
                Writer out = new FileWriter(dir + "/test01_out.txt");  
                
                //执行合并,会将合并后的文本输出到指定的地方
                template.process(root, out);
                
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            }  
        }

    B、ftl文件:test01.ftl(后缀名可以为其他,如html)

    listvalue:<#-- 正常显示的文本信息 -->  
      
        <#list list as v>  
            ${v} - ${v_index} [${v_has_next?string("y","n")}]  
        </#list> 

    C、生成的文本:test01_out.txt

    listvalue:  
      
            listvalue0 - 0 [y]  
            listvalue1 - 1 [y]  
            listvalue2 - 2 [y]  
            listvalue3 - 3 [y]  
            listvalue4 - 4 [y]  
            listvalue5 - 5 [y]  
            listvalue6 - 6 [y]  
            listvalue7 - 7 [y]  
            listvalue8 - 8 [y]  
            listvalue9 - 9 [n] 

    四、与WEB容器整合:
    通常我们会在WEB容器中使用Freemarker,用于生成前台需要的页面,这里介绍Freemarker与spring的整合步骤.
    在spring中提供了一个类org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer,可以通过在Controller中注入该类获取Freemarker的Configuration获取到Configuration后即可按照需求生成所要的页面和结果。

    A、spring中的配置信息:

    <bean id="text_cut" class="com.test.TextCutDirective"/><!--实现了freemarker.template.TemplateDirectiveModel接口-->
    <bean id="freemarkerTest" class="com.test.FreemarkerTest">
        <property name="freeMarkerConfigurer">
            <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> 
                <property name="freemarkerVariables">
                    <!--
                        FreeMarkerConfigurer.setFreemarkerVariables(Map<String,Object> variables)
                           底层调用了FreeMarker的Configuration.setAllSharedVariables()方法。
                           因为更好的实践是将常用的指令作为共享变量放到Configuration中,使用方式见下面的示例。
                        [@text_cut source='abcdefghijklmnopqrstuvwxyz' length='12'/]
                        即从Configuration中获取text_cut对应的处理类,执行TemplateDirectiveModel.execute(...)
                    -->
                        <map>
                            <entry key="text_cut" value-ref="text_cut"/><!--本文只提供该类的实现,其他如process_time类似-->
                            <entry key="process_time" value-ref="process_time"/>
                        </map>
                </property>
                <!--模板的加载路径-->
                <property name="templateLoaderPath" value="/WEB-INF" /> 
                <property name="freemarkerSettings"> 
                    <props> 
                        <prop key="template_update_delay">0</prop><!--模板刷新的时间,如果经常调试就用0 了--> 
                        <prop key="defaultEncoding">UTF-8</prop> 
                        <prop key="url_escaping_charset">UTF-8</prop> 
                        <prop key="locale">zh_CN</prop> 
                        <prop key="boolean_format">true,false</prop> 
                        <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> 
                        <prop key="date_format">yyyy-MM-dd</prop> 
                        <prop key="time_format">HH:mm:ss</prop> 
                        <prop key="number_format">0.######</prop> 
                        <prop key="whitespace_stripping">true</prop> 
                        <prop key="auto_import">/ftl/index.ftl as p</prop>
                        <!--auto_import这个是关键了,就是自动加载的模板,我们为了减少手动加载,大可以在这里让程序自动加载,
                        但是又不能在这里写太多的文件名,所以就可以使用include指令,在index.ftl中include其他的ftl文件加载,
                        这样就可以将项目中所有的ftl文件加载进来--> 
                    </props> 
                </property> 
            </bean>
        </property>
    </bean> 

    B、FreeMarkerTest代码:

    @Service
    public class FreeMarkerTest {
        
        private Configuration conf;
        
        //只需提供setter即可
        public void setFreeMarkerConfigurer(
                FreeMarkerConfigurer freeMarkerConfigurer) {
            this.conf = freeMarkerConfigurer.getConfiguration();
        }
        
        /**
         * 对外提供的接口
         * @throws IOException 
         * @throws TemplateException 
         */
        public void excute(String tplName, Map<String, Object> data, HttpServletResponse response) throws TemplateException, IOException {
            
            Writer out = null;
            
            try {
                
                //...此处可以根据需求指定模板的名称
                Template template = conf.getTemplate(tplName);
                
                //此处指定输出到客户端
                out = response.getWriter();
                template.process(data, response.getWriter());
                
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                
                if(out != null) {
                    out.flush();
                    out.close();
                }
            }
        }
    
    }

    C、TextCutDirective代码:

    public class TextCutDirective implements TemplateDirectiveModel{
    
        @SuppressWarnings("unchecked")
        public void execute(Environment env, Map params, TemplateModel[] loopVars,
                TemplateDirectiveBody body) throws TemplateException, IOException {
            
            //模板指令中传递的参数
            String s = DirectiveUtils.getString("source", params);
            Integer len = DirectiveUtils.getInt("length", params);
            
            if(s != null && s.length() < len) {
                s = s.substring(0, len);
            }
            
            if (s != null) {
                Writer out = env.getOut();
                if (len != null) {
                    out.append(s);
                } else {
                    out.append(s);
                }
            }
        }
    
    }

    D、ftl文件:test02.ftl(后缀名可以为其他,如html)

    [@text_cut source='abcdefghijklmnopqrstuvwxyz' length='12'/]

    E、运行结果:

    abcdefghijkl
  • 相关阅读:
    Hibernate之HQL查询
    Java设计模式----状态模式(State)
    Java设计模式----备忘录模式(Memento)
    Java设计模式----命令模式(Command)
    Java设计模式----责任链模式(Chain of Responsibility)
    Java基础小知识
    Hibernate检索策略
    Java设计模式----观察者模式(Observer)
    Google代码实验室
    Codeforces Round #257 (Div. 2) 前四题
  • 原文地址:https://www.cnblogs.com/tq03/p/3491007.html
Copyright © 2011-2022 走看看