一、创建 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()); } } } }四、实用类
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);
相关推荐
l 虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图) l FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件 l ...
freemarker的开发学习,从入门到能够用freemarker写出一些程序,是入门和提高的好文档
第二部分 程序开发指南 ................................................................................................. 62 第一章 程序开发入门 ............................................................
程序开发软件: Eclipse/Idea + mysql8.0 现在给大家看的是一个基于Springboot框架+FreeMarker模板引擎的旅游景点交流论坛网站,网站一个有2个身份,普通用户和管理员。管理员登录后可以进入后台管理网站导航栏目,...
同时,JessMA为应用开发提供了大量Util工具,用来处理应用程序开发过程中通常会遇到的一般性问题,进一步减少应用程序开发者的工作负担。 6) 平缓的学习曲线:学习使用JessMA只需掌握一定的Core Java与JSP/Servlet...
在本系列教程中我们将学习到Struts2的各种技术。在本教程中使用的工具和程序库的版本如下: 开发工具:MyEclipse8.5 Web服务器:Tomcat6 Struts版本:struts2.1.6.jar JDK版本:JDK1.6.0_33-b03 J2EE版本:Java...
后端主要用到的技术: JDK8、MySql、SpringBoot、Spring—data-jpa、Lombok、Freemarker、Bootstrap、WebSocket 前端主要用到的技术: 微信小程序开发 -------- <项目介绍> 该资源内项目源码是个人的毕设,代码都...
使用Spring JdbcTemplate+Druid数据源+FreeMarker 开发的代码生成器。 您可以根据自己的实际,修改一下FreeMarker的模版文件,直接按目录生成Java代码。 生成了就能用,节省大量重复工作的时间。 您也可以用来学习...
为了简化开发并实现程序解耦,选用了Spring Boot框架去搭建后台,在此基础上使用Mybatis连接数据库,避免了繁琐的JDBC代码,利用Freemarker框架减少了业务逻辑代码在表现层的耦合并实现数据展示,从0到1设计并开发了...
第二部分 程序开发指南 ................................................................................................. 61 第一章 程序开发入门 ............................................................
第二部分 程序开发指南 ................................................................................................. 61 第一章 程序开发入门 ............................................................
框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。 它提供了对ORM工具(Hibernate,JDO,TopLink,apacheOJB,iBatis,JPA)、视图(JSP,JSTL,Title,Velocity...
本程序是作者学习struts spring hibernate构架后为了练习开发的一个小程序。开发此程序的目的是为了验证框架技术在项目中的应用。本程序尽量包含了开发当中遇到的一些问题及解决方案。同时欢迎广大网友到作者的群内...
本程序是作者学习struts spring hibernate构架后为了练习开发的一个小程序。开发此程序的目的是为了验证框架技术在项目中的应用。本程序尽量包含了开发当中遇到的一些问题及解决方案。同时欢迎广大网友到作者的群内...
后端主要用到的技术: JDK8、MySql、SpringBoot、Spring—data-jpa、Lombok、Freemarker、Bootstrap、WebSocket 前端主要用到的技术: 微信小程序开发 【备注】 主要针对计算机相关专业的正在做毕设的学生和需要项目...
前端使用LayUI框架 + freemarker动态模板生成 数据库使用MySQL MVC三层架构 【备注】 主要针对计算机相关专业的正在做毕设的学生和需要项目实战的Java学习者。 也可作为课程设计、期末大作业。包含:项目源码、...
程序开发软件: Eclipse/Idea + mysql8.0 现在给大家看的是一个基于Springboot框架+FreeMarker模板引擎的旅游景点交流论坛网站,网站一个有2个身份,普通用户和管理员。管理员登录后可以进入后台管理网站导航栏目...
带领大家借助当下比较...大家只需要跟着老师一步步学习,我们既可以学习到java知识,也可以学习到小程序开发和web开发相关的知识。 我们学习过程中会有老师在线实时解答,每节课都会有对应的源码和配套笔记给到大家。
本软件采用jsp+sqlserver+ hibernate+struts实现,并使用了freemarker静态化、会员登录的状态以及文章点击使用ajax动态处理。本系统以学习技术为...备注:可能较长时间没有进行程序开发,系统不完善,仅作学习之用!
系统后端采用Springboot进行开发,包含ManageServer和CommServer两个模块,ManagerServer负责具体的业务,CommServer负责公共的功能,比如微信公众号/小程序模板及订阅消息推送,定时任务,发送短信等,实现多种调度...