`

Freemarker学习--程序开发

阅读更多

一、创建 Configuration 实例

 

Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
cfg .setClassForTemplateLoading(this.getClass(), "ftl");

cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

 不需要重复创建 Configuration 实例; 它的代价很高,尤其是会丢失缓存。Configuration实例就是应用级别的单例。

 

二、获取模板

Template temp = cfg.getTemplate("hashes.ftl");

Configuration 缓存 Template 实例,当再次获得 hashes.ftl 的时候,它可能再读取和解析模板文件了, 而只是返回第一次的 Template实例。

三、数据模型

在内部,模板中可用的变量都是实现了freemarker.template.TemplateModel 接口的Java对象。 但在数据模型中,可以使用基本的Java集合类作为变量,因为这些变量会在内部被替换为适当的 TemplateModel 类型,类freemarker.template.ObjectWrapper的职责

A、标量

有4种类型的标量:

  • 布尔值
  • 数字
  • 字符串
  • 日期类型(子类型: 日期(没有时间部分),时间或者日期-时间)

每一种标量类型都是 TemplateTypeModel 接口的实现,这里的 Type 就是类型的名称。这些接口只定义了一个方法: typegetAsType();。 它返回变量的Java类型(boolean, Number, String 和 Date 各自代表的值)。

B、哈希表 对应TemplateHashModel 

C、序列对应TemplateSequenceModel  

D、集合 对应TemplateCollectionModel 

E、方法对应TemplateMethodModel 

方法示例:

public class IndexOfMethod implements TemplateMethodModel {
    
    public TemplateModel exec(List args) throws TemplateModelException {
        if (args.size() != 2) {
            throw new TemplateModelException("Wrong arguments");
        }
        return new SimpleNumber(
            ((String) args.get(1)).indexOf((String) args.get(0)));
    }
}

如果将一个实例放入根数据模型中,像这样:

root.put("indexOf", new IndexOfMethod());

那么就可以在模板中调用:

<#assign x = "something">
${indexOf("met", x)}
${indexOf("foo", x)}

将会输出:

2
-1

 F、指令 对应TemplateDirectiveModel 

我们来创建一个指令,这个指令可以一次又一次地执行其中的嵌套内容, 这个次数由指定的数字来确定(就像 list 指令), 可以使用<hr>将输出的重复内容分开。 这个指令我们命名为"repeat"。示例模板如下:

<#assign x = 1>

<@repeat count=4>
  Test ${x}
  <#assign x++>
</@repeat>

<@repeat count=3 hr=true>
  Test
</@repeat>

<@repeat count=3; cnt>
  ${cnt}. Test
</@repeat>

输出为:

  Test 1
  Test 2
  Test 3
  Test 4

  Test
<hr>  Test
<hr>  Test

  1. Test
  2. Test
  3. Test
指令的实现类为:
public class RepeatDirective implements TemplateDirectiveModel {
    
    private static final String PARAM_NAME_COUNT = "count";
    private static final String PARAM_NAME_HR = "hr";
    
    public void execute(Environment env,
            Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body)
            throws TemplateException, IOException {
        
        // ---------------------------------------------------------------------
        // Processing the parameters:
        
        int countParam = 0;
        boolean countParamSet = false;
        boolean hrParam = false;
        
        Iterator paramIter = params.entrySet().iterator();
        while (paramIter.hasNext()) {
            Map.Entry ent = (Map.Entry) paramIter.next();
            
            String paramName = (String) ent.getKey();
            TemplateModel paramValue = (TemplateModel) ent.getValue();
            
            if (paramName.equals(PARAM_NAME_COUNT)) {
                if (!(paramValue instanceof TemplateNumberModel)) {
                    throw new TemplateModelException(
                            "The \"" + PARAM_NAME_HR + "\" parameter "
                            + "must be a number.");
                }
                countParam = ((TemplateNumberModel) paramValue)
                        .getAsNumber().intValue();
                countParamSet = true;
                if (countParam < 0) {
                    throw new TemplateModelException(
                            "The \"" + PARAM_NAME_HR + "\" parameter "
                            + "can't be negative.");
                }
            } else if (paramName.equals(PARAM_NAME_HR)) {
                if (!(paramValue instanceof TemplateBooleanModel)) {
                    throw new TemplateModelException(
                            "The \"" + PARAM_NAME_HR + "\" parameter "
                            + "must be a boolean.");
                }
                hrParam = ((TemplateBooleanModel) paramValue)
                        .getAsBoolean();
            } else {
                throw new TemplateModelException(
                        "Unsupported parameter: " + paramName);
            }
        }
        if (!countParamSet) {
                throw new TemplateModelException(
                        "The required \"" + PARAM_NAME_COUNT + "\" paramter"
                        + "is missing.");
        }
        
        if (loopVars.length > 1) {
                throw new TemplateModelException(
                        "At most one loop variable is allowed.");
        }
        
        // Yeah, it was long and boring...
        
        // ---------------------------------------------------------------------
        // Do the actual directive execution:
        
        Writer out = env.getOut();
        if (body != null) {
            for (int i = 0; i < countParam; i++) {
                // Prints a <hr> between all repetations if the "hr" parameter
                // was true:
                if (hrParam && i != 0) {
                    out.write("<hr>");
                }
                
                // Set the loop variable, if there is one:
                if (loopVars.length > 0) {
                    loopVars[0] = new SimpleNumber(i + 1);
                }
                
                // Executes the nested body (same as <#nested> in FTL). In this
                // case we don't provide a special writer as the parameter:
                body.render(env.getOut());
            }
        }
    }

}
 四、实用类
1、访问静态方法
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel staticModels = wrapper.getStaticModels();
TemplateHashModel fileStatics =
    (TemplateHashModel) staticModels.get("java.io.File");
 2、访问枚举类型
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel enumModels = wrapper.getEnumModels();
TemplateHashModel roundingModeEnums =
    (TemplateHashModel) enumModels.get("java.math.RoundingMode");
 3、自定义模版加载
FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2, ctl };
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);

cfg.setTemplateLoader(mtl);
 
分享到:
评论

相关推荐

    FreeMarker 学习资料

    l 虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图) l FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件 l ...

    Freemarker 中文版教程

    freemarker的开发学习,从入门到能够用freemarker写出一些程序,是入门和提高的好文档

    超完整FreeMarker中文教程,代码

    第二部分 程序开发指南 ................................................................................................. 62 第一章 程序开发入门 ............................................................

    基于Springboot+FreeMarker实现的旅游景点交流论坛网设计源码+源代码+文档说明+sql文件

    程序开发软件: Eclipse/Idea + mysql8.0 现在给大家看的是一个基于Springboot框架+FreeMarker模板引擎的旅游景点交流论坛网站,网站一个有2个身份,普通用户和管理员。管理员登录后可以进入后台管理网站导航栏目,...

    JessMA Java Web 应用开发框架 (v3.2.2-20130815).pdf

    同时,JessMA为应用开发提供了大量Util工具,用来处理应用程序开发过程中通常会遇到的一般性问题,进一步减少应用程序开发者的工作负担。 6) 平缓的学习曲线:学习使用JessMA只需掌握一定的Core Java与JSP/Servlet...

    Struts2教程配套源码

    在本系列教程中我们将学习到Struts2的各种技术。在本教程中使用的工具和程序库的版本如下: 开发工具:MyEclipse8.5 Web服务器:Tomcat6 Struts版本:struts2.1.6.jar JDK版本:JDK1.6.0_33-b03 J2EE版本:Java...

    基于SpringBoot前后端分离的点餐系统+源代码+文档说明

    后端主要用到的技术: JDK8、MySql、SpringBoot、Spring—data-jpa、Lombok、Freemarker、Bootstrap、WebSocket 前端主要用到的技术: 微信小程序开发 -------- &lt;项目介绍&gt; 该资源内项目源码是个人的毕设,代码都...

    Spring使用Druid整合JdbcTemplate与FreeMarker实例 下载

    使用Spring JdbcTemplate+Druid数据源+FreeMarker 开发的代码生成器。 您可以根据自己的实际,修改一下FreeMarker的模版文件,直接按目录生成Java代码。 生成了就能用,节省大量重复工作的时间。 您也可以用来学习...

    基于Spring Boot的购物商城的设计与开发

    为了简化开发并实现程序解耦,选用了Spring Boot框架去搭建后台,在此基础上使用Mybatis连接数据库,避免了繁琐的JDBC代码,利用Freemarker框架减少了业务逻辑代码在表现层的耦合并实现数据展示,从0到1设计并开发了...

    FreeMarker 手册

    第二部分 程序开发指南 ................................................................................................. 61 第一章 程序开发入门 ............................................................

    FreeMarker中文指导手册

    第二部分 程序开发指南 ................................................................................................. 61 第一章 程序开发入门 ............................................................

    SSH相关整合的总要资料

    框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。 它提供了对ORM工具(Hibernate,JDO,TopLink,apacheOJB,iBatis,JPA)、视图(JSP,JSTL,Title,Velocity...

    Bug管理系统 struts2+sping2.5+hibernate3(1-2)

    本程序是作者学习struts spring hibernate构架后为了练习开发的一个小程序。开发此程序的目的是为了验证框架技术在项目中的应用。本程序尽量包含了开发当中遇到的一些问题及解决方案。同时欢迎广大网友到作者的群内...

    Bug管理系统 struts2+sping2.5+hibernate3(2-2)

    本程序是作者学习struts spring hibernate构架后为了练习开发的一个小程序。开发此程序的目的是为了验证框架技术在项目中的应用。本程序尽量包含了开发当中遇到的一些问题及解决方案。同时欢迎广大网友到作者的群内...

    基于SpringBoot前后端分离的点餐系统源码+项目说明.zip

    后端主要用到的技术: JDK8、MySql、SpringBoot、Spring—data-jpa、Lombok、Freemarker、Bootstrap、WebSocket 前端主要用到的技术: 微信小程序开发 【备注】 主要针对计算机相关专业的正在做毕设的学生和需要项目...

    基于SpringBoot开发的校内信息共享平台源码+项目说明.zip

    前端使用LayUI框架 + freemarker动态模板生成 数据库使用MySQL MVC三层架构 【备注】 主要针对计算机相关专业的正在做毕设的学生和需要项目实战的Java学习者。 也可作为课程设计、期末大作业。包含:项目源码、...

    基于Springboot+FreeMarker全国旅游景点交流平台源码+sql数据库(毕设源码).zip

    程序开发软件: Eclipse/Idea + mysql8.0 现在给大家看的是一个基于Springboot框架+FreeMarker模板引擎的旅游景点交流论坛网站,网站一个有2个身份,普通用户和管理员。管理员登录后可以进入后台管理网站导航栏目...

    java后台开发入门(springboot快速入门)

    带领大家借助当下比较...大家只需要跟着老师一步步学习,我们既可以学习到java知识,也可以学习到小程序开发和web开发相关的知识。 我们学习过程中会有老师在线实时解答,每节课都会有对应的源码和配套笔记给到大家。

    内容管理系统 jsp+hibernate+struts

    本软件采用jsp+sqlserver+ hibernate+struts实现,并使用了freemarker静态化、会员登录的状态以及文章点击使用ajax动态处理。本系统以学习技术为...备注:可能较长时间没有进行程序开发,系统不完善,仅作学习之用!

    全民经纪人后台管理系统.rar

    系统后端采用Springboot进行开发,包含ManageServer和CommServer两个模块,ManagerServer负责具体的业务,CommServer负责公共的功能,比如微信公众号/小程序模板及订阅消息推送,定时任务,发送短信等,实现多种调度...

Global site tag (gtag.js) - Google Analytics