您的位置:首页 > 其它

Freemarker模板应用

2015-05-08 21:55 295 查看
转载于:/article/4096289.html

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

模板用servlet提供的数据动态地生成 HTML,模板语言是强大的直观的,编译器速度快,

输出接近静态HTML页面的速度。

一.Freemarker模板应用事例。

1.创建模板文件,在/resource/template目录下建立freemarkerLocal.ftl文件。

Java代码







------------------普通变量获取-------------------
${user}
---------获取Map中属性--------------
${latestProduct.url}
${latestProduct.name}
-------自定义的indexOf方法变量-------
<#assign x = "something">
${indexOf("met", x)}
${indexOf("foo", x)}
------自定义的转换器变量(转换小写为大写,以标签形式展现)----------------
blah1
<@upperCase>
blah2
blah3
</@upperCase>
blah4
---------------共享变量的获取,在Configuration中设置---------------
<@to_upper>
${company}
</@to_upper>

[java]
view plaincopy

<span style="font-size:18px;">------------------普通变量获取-------------------
${user}
---------获取Map中属性--------------
${latestProduct.url}
${latestProduct.name}
-------自定义的indexOf方法变量-------
<#assign x = "something">
${indexOf("met", x)}
${indexOf("foo", x)}
------自定义的转换器变量(转换小写为大写,以标签形式展现)----------------
blah1
<@upperCase>
blah2
blah3
</@upperCase>
blah4
---------------共享变量的获取,在Configuration中设置---------------
<@to_upper>
${company}
</@to_upper></span>

2.代码解析模板文件输出。

Java代码







public class FreemarkerLocalTest {

public static void main(String[] args) throws Exception {

/* 一般在应用的整个生命周期中你仅需要执行一下代码一次*/
/* 创建一个合适的configuration */
Configuration cfg = new Configuration();

// 设置模板加载的方式
cfg.setDirectoryForTemplateLoading(
new File("D:/myspace/freemarker/resource/template"));
// 方式二(从Web上下文获取)
// void setServletContextForTemplateLoading(Object servletContext, String path);

// 设置模板共享变量,所有的模板都可以访问设置的共享变量
cfg.setSharedVariable("to_upper", new UpperCaseTransform());
cfg.setSharedVariable("company","FooInc.");

// 指定模板如何查看数据模型
cfg.setObjectWrapper(new DefaultObjectWrapper());

// 如果从多个位置加载模板,可采用以下方式
/**

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);**/

/* 而以下代码你通常会在一个应用生命周期中执行多次*/
/*获取或创建一个模版*/
Template temp = cfg.getTemplate("freemarkerLocal.ftl");

/*创建一个数据模型Create a data model */
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");

// 方法变量,indexOf为自己定义的方法变量
root.put("indexOf", new IndexOfMethod());

// 转换器变量
root.put("upperCase", new UpperCaseTransform());

/* 合并数据模型和模版*/
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();
}
}

[java]
view plaincopy

<span style="font-size:18px;">public class FreemarkerLocalTest {

public static void main(String[] args) throws Exception {
/* 一般在应用的整个生命周期中你仅需要执行一下代码一次*/
/* 创建一个合适的configuration */
Configuration cfg = new Configuration();

// 设置模板加载的方式
cfg.setDirectoryForTemplateLoading(
new File("D:/myspace/freemarker/resource/template"));
// 方式二(从Web上下文获取)
// void setServletContextForTemplateLoading(Object servletContext, String path);

// 设置模板共享变量,所有的模板都可以访问设置的共享变量
cfg.setSharedVariable("to_upper", new UpperCaseTransform());
cfg.setSharedVariable("company","FooInc.");

// 指定模板如何查看数据模型
cfg.setObjectWrapper(new DefaultObjectWrapper());

// 如果从多个位置加载模板,可采用以下方式
/**
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);**/

/* 而以下代码你通常会在一个应用生命周期中执行多次*/
/*获取或创建一个模版*/
Template temp = cfg.getTemplate("freemarkerLocal.ftl");

/*创建一个数据模型Create a data model */
Map root = new HashMap();
root.put("user", "Big Joe");
Map latest = new HashMap();
root.put("latestProduct", latest);
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");

// 方法变量,indexOf为自己定义的方法变量
root.put("indexOf", new IndexOfMethod());

// 转换器变量
root.put("upperCase", new UpperCaseTransform());

/* 合并数据模型和模版*/
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();
}
}
</span>

3.自定义的方法变量类IndexOfMethod

Java代码







public class IndexOfMethod implements TemplateMethodModel {

public Object 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)));
}
}

[java]
view plaincopy

<span style="font-size:18px;">public class IndexOfMethod implements TemplateMethodModel {

public Object 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)));
}
}</span>

4.自定义的转换器变量类UpperCaseTransform

Java代码







/**
* 转换器变量,自定义自己的转换器标签
*/
import freemarker.template.TemplateTransformModel;

public class UpperCaseTransform implements TemplateTransformModel {

// 转换器接口方法,将会转换标签之间的内容,首先把标签之间的内容读取到Writer对象中,
// 再由Writer对象对其中的内容施行转换处理,转换后的内容会再次存储到Writer 中
public Writer getWriter(Writer out, Map args) {
return new UpperCaseWriter(out);
}
private class UpperCaseWriter extends Writer {
private Writer out;

UpperCaseWriter(Writer out) {
this.out = out;
}
public void write(char[] cbuf, int off, int len) throws IOException {

out.write(new String(cbuf, off, len).toUpperCase());
}

public void flush() throws IOException {
out.flush();
}
// 不用调用out.close,到达结束标签close会自动被调用
public void close() {

}
}
}

[java]
view plaincopy

<span style="font-size:18px;">/**
* 转换器变量,自定义自己的转换器标签
*/
import freemarker.template.TemplateTransformModel;

public class UpperCaseTransform implements TemplateTransformModel {

// 转换器接口方法,将会转换标签之间的内容,首先把标签之间的内容读取到Writer对象中,
// 再由Writer对象对其中的内容施行转换处理,转换后的内容会再次存储到Writer 中
public Writer getWriter(Writer out, Map args) {
return new UpperCaseWriter(out);
}
private class UpperCaseWriter extends Writer {
private Writer out;

UpperCaseWriter(Writer out) {
this.out = out;
}
public void write(char[] cbuf, int off, int len) throws IOException {
out.write(new String(cbuf, off, len).toUpperCase());
}

public void flush() throws IOException {
out.flush();
}
// 不用调用out.close,到达结束标签close会自动被调用
public void close() {

}
}
}</span>

二.自动生成代码应用

1.创建模板文件,在/resource/template目录下建立codeModel.ftl文件。

Java代码







package com.order.model;

public class ${class} {

<#list properties as prop>
private ${prop.type} ${prop.name};
</#list>

<#list properties as prop>
public ${prop.type} get${prop.name?cap_first}(){
return ${prop.name};
}
public void set${prop.name?cap_first}(${prop.type} ${prop.name}){
this.${prop.name} = ${prop.name};
}
</#list>

}

[java]
view plaincopy

<span style="font-size:18px;">package com.order.model;

public class ${class} {

<#list properties as prop>
private ${prop.type} ${prop.name};
</#list>

<#list properties as prop>
public ${prop.type} get${prop.name?cap_first}(){
return ${prop.name};
}
public void set${prop.name?cap_first}(${prop.type} ${prop.name}){
this.${prop.name} = ${prop.name};
}
</#list>

}
</span>

2.应用代码生成模板文件。

Java代码







public class GenerateCodeTest {

public static void main(String args[]) throws IOException,

TemplateException {
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(
"D:/myspace/freemarker/resource/template/"));
cfg.setObjectWrapper(new DefaultObjectWrapper());

/* 获取模板文件 */
Template template = cfg.getTemplate("codeModel.ftl");

/* 模板数据 */
Map<String, Object> root = new HashMap<String, Object>();
root.put("class", "Order");
Collection<Map<String, String>> properties = new HashSet<Map<String, String>>();
root.put("properties", properties);

/* 字段1 orderId */
Map<String, String> orderId = new HashMap<String, String>();
orderId.put("name", "orderId");
orderId.put("type", "Long");
properties.add(orderId);

/* 字段2 orderName */
Map<String, String> orderName = new HashMap<String, String>();
orderName.put("name", "orderName");
orderName.put("type", "String");
properties.add(orderName);

/* 字段3 money */
Map<String, String> money = new HashMap<String, String>();
money.put("name", "money");
money.put("type", "Double");
properties.add(money);

/* 生成输出到控制台 */
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();

/* 生成输出到文件 */
File fileDir = new File("D:/generateCodeFile");
// 创建文件夹,不存在则创建
org.apache.commons.io.FileUtils.forceMkdir(fileDir);
// 指定生成输出的文件
File output = new File(fileDir + "/Order.java");
Writer writer = new FileWriter(output);
template.process(root, writer);
writer.close();
}
}

[java]
view plaincopy

<span style="font-size:18px;">public class GenerateCodeTest {

public static void main(String args[]) throws IOException,
TemplateException {
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(
"D:/myspace/freemarker/resource/template/"));
cfg.setObjectWrapper(new DefaultObjectWrapper());

/* 获取模板文件 */
Template template = cfg.getTemplate("codeModel.ftl");

/* 模板数据 */
Map<String, Object> root = new HashMap<String, Object>();
root.put("class", "Order");
Collection<Map<String, String>> properties = new HashSet<Map<String, String>>();
root.put("properties", properties);

/* 字段1 orderId */
Map<String, String> orderId = new HashMap<String, String>();
orderId.put("name", "orderId");
orderId.put("type", "Long");
properties.add(orderId);

/* 字段2 orderName */
Map<String, String> orderName = new HashMap<String, String>();
orderName.put("name", "orderName");
orderName.put("type", "String");
properties.add(orderName);

/* 字段3 money */
Map<String, String> money = new HashMap<String, String>();
money.put("name", "money");
money.put("type", "Double");
properties.add(money);

/* 生成输出到控制台 */
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();

/* 生成输出到文件 */
File fileDir = new File("D:/generateCodeFile");
// 创建文件夹,不存在则创建
org.apache.commons.io.FileUtils.forceMkdir(fileDir);
// 指定生成输出的文件
File output = new File(fileDir + "/Order.java");
Writer writer = new FileWriter(output);
template.process(root, writer);
writer.close();
}
}</span>

三.JSP调用模板文件输出。

1.首先创建模板文件,在WEB-INF/templates目录下建立test.ftl文件。

Java代码







Hello,${name}!

[java]
view plaincopy

<span style="font-size:18px;">Hello,${name}!
</span>

2.解析模板文件类,传入pageContext参数。

Java代码







public class FreemarkerTest {

public void execute(PageContext pageContext) throws Exception
{
Configuration cfg = new Configuration();
// 设置模板的路径
cfg.setServletContextForTemplateLoading(pageContext.getServletContext(),
"WEB-INF/templates");
Map root = new HashMap();
root.put("name", "Tom");
// 获取模板文件
Template t = cfg.getTemplate("test.ftl");
Writer out = pageContext.getResponse().getWriter();
t.process(root, out);
}
}

[java]
view plaincopy

<span style="font-size:18px;">public class FreemarkerTest {

public void execute(PageContext pageContext) throws Exception
{
Configuration cfg = new Configuration();
// 设置模板的路径
cfg.setServletContextForTemplateLoading(pageContext.getServletContext(),
"WEB-INF/templates");
Map root = new HashMap();
root.put("name", "Tom");
// 获取模板文件
Template t = cfg.getTemplate("test.ftl");
Writer out = pageContext.getResponse().getWriter();
t.process(root, out);
}
}
</span>

3.创建JSP文件调用输出。

Html代码







<%@ page language="java" contentType="text/html; charset=GB2312"
pageEncoding="GB2312"%>
<%@page import="com.freemarker.test.FreemarkerTest;"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<title>HelloWorld</title>
</head>
<body>
<%
FreemarkerTest c1 = new FreemarkerTest();
c1.execute(pageContext);
%>
</body>
</html>

[html]
view plaincopy

<span style="font-size:18px;"><%@ page language="java" contentType="text/html; charset=GB2312"
pageEncoding="GB2312"%>
<%@page import="com.freemarker.test.FreemarkerTest;"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<title>HelloWorld</title>
</head>
<body>
<%
FreemarkerTest c1 = new FreemarkerTest();
c1.execute(pageContext);
%>
</body>
</html></span>

四.Servlet调用模板文件生成html文件进行页面展示。

1.创建模板文件,在WebRoot/index目录下建立test.ftl文件。

Java代码







<html>
<body>
用户名:${userName}<br>
邮  箱:${email}
</body>
</html>

[java]
view plaincopy

<span style="font-size:18px;"><html>
<body>
用户名:${userName}<br>
邮  箱:${email}
</body>
</html></span>

2.创建Servlet文件解析模板文件并生成html文件进行页面输出。

Java代码







public class FreemarkerServletTest extends HttpServlet {

public FreemarkerServletTest() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//生成html后的文件
String path = getServletContext().getRealPath("/") + "index.htm";
System.out.println(path);
try {
freemarker(request, "test.ftl", path, "index");
} catch (Exception e) {
e.printStackTrace();
}
//跳转到刚生成的html文件中
request.getRequestDispatcher("/index.htm").forward(request, response);
}

/**

* 生成静态文件

* @param request
* @param ftl ftl文件
* @param html 生成html后的文件
* @param file 存放ftl文件的路径
* @throws Exception
*/
public void freemarker(HttpServletRequest request,String ftl,
String html,String file) throws Exception {
Configuration cfg = new Configuration();
// 设置加载模板的路径
cfg.setServletContextForTemplateLoading(getServletContext(),"/" + file);
cfg.setEncoding(Locale.getDefault(), "GB18030");

//获得模板并设置编码
Template tep = cfg.getTemplate(ftl);
tep.setEncoding("GB18303");

//新建输出,生成html文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(html),"GB18030"));

//设置值

Map map = new HashMap();
map.put("userName", "wxj");
map.put("email", "jxauwxj@126.com");
// 解析并输出
tep.process(map, out);
}

public void init() throws ServletException {
}
}

[java]
view plaincopy

<span style="font-size:18px;">public class FreemarkerServletTest extends HttpServlet {

public FreemarkerServletTest() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//生成html后的文件
String path = getServletContext().getRealPath("/") + "index.htm";
System.out.println(path);
try {
freemarker(request, "test.ftl", path, "index");
} catch (Exception e) {
e.printStackTrace();
}
//跳转到刚生成的html文件中
request.getRequestDispatcher("/index.htm").forward(request, response);
}

/**
* 生成静态文件
* @param request
* @param ftl ftl文件
* @param html 生成html后的文件
* @param file 存放ftl文件的路径
* @throws Exception
*/
public void freemarker(HttpServletRequest request,String ftl,
String html,String file) throws Exception {
Configuration cfg = new Configuration();
// 设置加载模板的路径
cfg.setServletContextForTemplateLoading(getServletContext(),"/" + file);
cfg.setEncoding(Locale.getDefault(), "GB18030");

//获得模板并设置编码
Template tep = cfg.getTemplate(ftl);
tep.setEncoding("GB18303");

//新建输出,生成html文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(html),"GB18030"));
//设置值
Map map = new HashMap();
map.put("userName", "wxj");
map.put("email", "jxauwxj@126.com");
// 解析并输出
tep.process(map, out);
}

public void init() throws ServletException {
}
}</span>

3.web.xml文件进行servlet配置。

Xml代码







<servlet>
<servlet-name>FreemarkerServletTest</servlet-name>
<servlet-class>com.servlet.FreemarkerServletTest</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>FreemarkerServletTest</servlet-name>
<url-pattern>/servlet/FreemarkerServletTest</url-pattern>
</servlet-mapping>

[xml]
view plaincopy

<span style="font-size:18px;"><servlet>
<servlet-name>FreemarkerServletTest</servlet-name>
<servlet-class>com.servlet.FreemarkerServletTest</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>FreemarkerServletTest</servlet-name>
<url-pattern>/servlet/FreemarkerServletTest</url-pattern>
</servlet-mapping></span>

4.页面访问如下Url:

http://localhost:8080/freemarkerWeb/servlet/FreemarkerServletTest

输出结果如下:

Java代码







用户名:wxj
邮 箱:jxauwxj@126.com

[java]
view plaincopy

<span style="font-size:18px;">用户名:wxj
邮 箱:jxauwxj@126.com</span>

同时会在部署环境的目录下生成index.htm文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: