浅谈 FreeMarker 模板引擎

本贴最后更新于 2325 天前,其中的信息可能已经时异事殊

原文地址 https://www.heayan.com/articles/2018/02/28/1519825125353.html

前言

FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML 网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个 Java 类库,是一款程序员可以嵌入他们所开发产品的组件。模板编写为 FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像 PHP 那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。

模板引擎分为前台模板引擎、后台模板引擎,FreeMarker 是一款后台模板引擎。由于浏览器 JavaScript 脚本可以人为禁用,建议在使用模板引擎时,优先考虑后台模板引擎。本文以 FreeMarker2.3.26 版本作为分析对象。

工作原理

FreeMarker 通过数据模型、模板,进行组装获得输出对象。输出对象可以是 HTML 页面、电子邮件、配置文件、源代码等。FreeMarker 的模板编写,需要使用 FTL 标签库 FTL 标签库。FTL 标签库类似于 JSTL 标签库,后台通过 JSTL 标签库,将 JSP 文件中的变量动态替换为数据;FreeMarker 通过 FTL 标签库,将模板中的变量动态替换为数据。如图所示:

overview.png

示例代码

FreeMarker 模板示例。通过创建一个 HTML 文件,后缀改为.ftl 格式,将需要动态解析的数据用表达式代替。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>FreeMarker Template Demo</title>
</head>
<body>
	欢迎来到${name}宠物商店,我们的联系地址是${address},目前我们有以下宠物待售:
	<table>
		<tr>
			<td>昵称</td>
			<td>品种</td>
		</tr>
		<#list dogs as dog>
		<tr>
			<td>${dog.name}</td>
			<td>${dog.varieties}</td>
		</tr>
		</#list>
	</table>
</body>
</html>

FreeMarke 支持哈希表、序列、集合等数据类型,这些数据类型的数据都可以作为数据模型直接使用,而无需额外创建对象封装。最后,将数据模型与模板整合、输出或保存。

package demo.freemarker.servlet;

import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import demo.freemarker.entity.Dog;
import demo.freemarker.entity.Store;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

public class FreeMarkerServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7620561776035469936L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		/*数据模型data-model */
		Dog d1 = new Dog("d1", "小花狗", "德国牧羊犬");
		Dog d2 = new Dog("d2", "大黄狗", "哈士奇");
		Dog d3 = new Dog("d3", "小咖啡", "泰迪");
		List<Dog> dogs = new ArrayList<Dog>();
		dogs.add(d1);
		dogs.add(d2);
		dogs.add(d3);
		Store store = new Store("st1", "宠物专卖北京店", "北京市海淀区",dogs);

		try {
			/*配置信息*/
			Configuration cfg = new Configuration(Configuration.VERSION_2_3_26);
			cfg.setDirectoryForTemplateLoading(new File(req.getSession().getServletContext()
					.getRealPath("/freemarker")));//文件目录路径
			cfg.setDefaultEncoding("UTF-8");
			cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

			/*模板*/
			Template temp = cfg.getTemplate("storetemp.ftl");
			/*数据模型与模板组合*/
			Writer out = new OutputStreamWriter(System.out);
			temp.process(store, out);
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
}

应用场景

截至目前,、腾讯新闻、网易新闻、阿里巴巴采购批发等等网站,均对模板引擎有所应用。具体使用的是前台模板引擎,还是后天模板引擎,尚且无法知晓。有小伙伴可能会问为什么要使用模板引擎?使用模板引擎将页面静态化,一可以在页面在页面访问过程中,无需再次访问数据库,降低响应延迟。二有助于搜索引擎收录,有利于 SEO 优化。

版权声明:版权所有,转载请注明原文地址。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
Heayan
黑夜给了我黑色的眼睛,我却用它来寻找光明。 北京