Java模板引擎 FreeMarker

概念


FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。

它是为Java程序猿提供的一个开发包。它不是面向终于用户的,而是为程序猿提供的一款能够嵌入他们所开发产品的应用程序。



介绍


那么。FreeMarker是一款如何的工具呢?FreeMarker实际上是被设计用来生成HTML Web页面,尤其是通过实现了基于MVC模式的Java Servlet应用程序。使用MVC模式的动态页面的设计构思使得你能够将前端设计师从程序猿中分离出来。全部人各司其职,发挥其最擅长的一面。

网页设计师能够改写页面的显示效果而不受程序猿编译代码的影响,由于应该程序的逻辑和页面设计已经被分开了。页面模板代码不会收到复杂程序代码的影响。

这样的分离的思想即便对一个程序猿和页面设计师是同一个人的项目来说也都是很实用的,由于分离使得代码保持简洁并且易于维护。


虽然FreeMarker也拥有一些编程能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(例如以下图)。


FreeMarker不是一个Web应用框架。而适合作为Web应用框架的一个组件。可是FreeMarker引擎本身并不知道HTTP协议或Java Servlet的存在。它只来生成文本内容。既然是这样,它也很适用于非Web应用程序的开发环境。知识要注意的是。我们使用FreeMarker作为视图层的组件,是为了给诸如Struts这种Model2应用框架提供现成的解决方式,你也能够在模板中使用JSP标记库。



特性

  • 通用目标
易于嵌入到你的产品中,轻量级,不须要Servlet环境

可以生成各种文本:HTML、XML、RTF、Java源码等等

插件式模板加载器。能够从不论什么源加载模板。如本地文件、数据库等等

你能够按自己所需生成文本,保存到本地文件。作为Email发送,从Web应用程序发送它返回给Web浏览器

  • 强大的模板语言
在模板中创建和改变变量

命名的宏,能够具有位置參数和嵌套内容

差点儿在不论什么地方都能够使用复杂表达式来指定值

全部经常使用的指令,include、if/elseif/else、循环结构

名字空间有助于建立和维护可重用的宏库,或者将一个大project分成模块,而不必操心名字冲突

输出转换块,在嵌套模板片段生成输出时。转换HTML转义、压缩、语法高亮等等。你能够定义自己的转换

  • 通用数据模型
FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示

你能够使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等),告诉模板开发人员用法。使其不受技术细节的打搅

  • 为Web准备
支持JSP标记库

可以集成到Model2 Web应用框架中作为JSP的替代

在模板语言中内建处理典型Web相关任务(如HTML转义)的结构

为MVC模式设计,分离可视化设计和应用程序逻辑,分离页面设计师和程序猿

  • 智能的国际化和本地化
数字格式本地化敏感

多种不同语言的同样模板

日期和时间格式本地化敏感

字符集智能化(内部使用UNICODE)

非US字符集能够用作标识(如变量名)

  • 强大的XML处理能力
在模板中清楚和直觉的訪问XML对象模型

<#recurse>和<#visit>指令用于递归遍历XML树


优势

  • 能够彻底的分离表现层和业务逻辑
使用JSP开发过程中,在页面中大量的存在业务逻辑代码,使得页面的内容很混乱,在后期大量的改动维护过程中就变得很的困难。


FreeMarker不支持Java脚本代码。FreeMarker的原理是,模板+数据模型=输出。

模板仅仅负责数据在页面中的表现。不涉及不论什么的逻辑代码,而全部的逻辑都是由数据模型来处理的。用户终于看到的输出是模板和数据模型合并后创建的。


  • 能够提高开发效率
在以往的开发中。使用的都是JSP页面来展示数据的。即所谓的表现层。

我们都知道。JSP在第一次运行的时候须要转换成Servlet类,开发阶段进行功能调试时,须要频繁的改动JSP,每次改动都要编译和转换。那么试想一下,一天中我们浪费在程序编译的时间有多少。


相对于JSP来说。FreeMarker模板技术不存在编译和转换的问题,所以就不会存在上述问题。并且开发过程中,我们再不必等待界面设计开发者完毕页面原型后,我们再来开发程序。


并且,一些特定的系统。比方OA工作流系统中,就须要动态生成表单技术,这就为其提供了非常好的实现根据。

使得在整个流程的进行中。生成不同的表单就简单了非常多。

  • 使得开发过程中的人员分工更加明白
以往用JSP显示数据时,一些程序猿并不熟悉界面设计技术。反之界面开发者。也并不熟悉程序语言。对两者而言,交替性的工作本身就有难度。有时候稍有不慎。可能会将整个页面元素删除或去掉了某个程序符号。使得页面走样或程序错误,这样就须要两方相互沟通协作,解决出现的问题。有时候由于项目中的时间、任务量等因素的存在,可能这个工作就由一个人来完毕,这样就可能加大某一方开发者的工作量。

使用FreeMarker后,作为界面开发者。仅仅专心创建HTML文件、图像以及Web页面的其它可视化方面,不用理会数据;而程序开发者则专注于系统实现。负责为页面准备要显示的数据。



不足

  • 在改动模板后,可能会看到已经过期的数据
使用FreeMarker模板技术,生成静态的HTML页面后。假设一旦模板改变。而没有及时更新模板生成的HTML页面的话。用户看到的就是过期的数据。 
  • FreeMarker的变量必须有值
FreeMarker模板技术在应用过程中,FreeMarker中的变量必需要赋值,假设不赋值,那么就会抛出异常。

FreeMarker没有一个默认的null处理。甚至也不接受一个null值。想避免错误就要应用if/elseif/else 指令进行判段,假设对每个变量都推断的话,那么则反而添加了编程的麻烦。 

  • FreeMarker的Map限定Key必须是String。其它数据类型无法操作
Map问题,即FreeMarker中不能支持非String的Key值。这样在进行一些复杂迭代时就须要作一些其它的转换。如将一个Map拆分为两个或多个Map。

  • FreeMarker不支持集群应用
为了编成的方便性,把序列化的东西都放到了Session中,如Session,request等。在开发的过程中确实方便,但假设将应用放到集群中,就会出现错误。

 



一个小Demo


首先。须要下载FreeMarker的jar包,这里提供一个下载链接:freemarker.jar

然后,将这个freemarker.jar放到Web项目的 WebRootWEB-INFlib 文件夹下

最后,我把自己写的測试类贴出来,分享一下。

FreemarkerTest类 代码
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import junit.framework.TestCase;

public class FreemarkerTest extends TestCase {

	private String dir = "E:/.../OA/TestTotal/src/com/bjsxt/oa/freemarker";

	public void testFreemarker() {
		Configuration cfg = new Configuration();

		try {
			// 从哪里载入模板文件
			cfg.setDirectoryForTemplateLoading(new File(dir));
			
			// 定义模版的位置,从类路径中,相对于FreemarkerManager所在的路径载入模版
			// cfg.setTemplateLoader(new ClassTemplateLoader(FreemarkerManager.class, "templates"))

			// 设置对象包装器
			cfg.setObjectWrapper(new DefaultObjectWrapper());

			// 设置异常处理器
			cfg
					.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

			// 定义数据模型
			Map root = new HashMap();
			root.put("abc", "世界。你好");

			// 通过freemarker解释模板,首先须要获得Template对象
			Template template = cfg.getTemplate("test.ftl");

			// 定义模板解释完毕之后的输出
			PrintWriter out = new PrintWriter(new BufferedWriter(
					new FileWriter(dir+"/out.txt")));

			
			try {
				// 解释模板
				template.process(root, out);
			} catch (TemplateException e) {
				e.printStackTrace();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


以下是定义的模板 test.ftl

test.flt 代码
第一个測试程序:${abc}


最后执行的结果例如以下

输出了out.txt文件,out.txt文件里的内容例如以下:
第一个測试程序:世界。你好



原文地址:https://www.cnblogs.com/lcchuguo/p/5183370.html