1.maven引入jar包
<!--freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
2.项目中WEB-INF目录下,导入struts-tags.tld(可从struts2的core.jar包解压后获取),建立文件夹放入模板文件(*.tld),如图
模板例子(来自网上的教材例子)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
<h2>1.字符串处理</h2>
<#assign msg=' this IS the Test of freemarker & output'> 后台放入字符串:${msg} ===== ${msg} <br>
html编码:${msg?html}<br> 转第一个字母大写:${msg?cap_first}<br>
<#-- 转第一个字母小写:${msg?lower_first}<br>-->
字符串大写:${msg?upper_case}<br> 字符串小写:${msg?lower_case}<br>
去左右空格:${msg?trim}<br>
空值判断:${msg?if_exists}<br> 默认值abc:${msg?default('abc')}<br>
输出纯文本:${r"c:/ad/dfa"}<br> 插入boolean值false:<#assign foo=false/>${foo?string('true','false')}<br>
取下标为2的字符:${msg[2]}<br> 取字串1-7:${msg[1..7]}<br>
字符串拼接: <#assign ab="abc"> ${"hello "+ab}/${"hello${ab}"} <br>
<hr>
<h2>2.数字处理</h2>
赋值 assign x=3.1415926<br>
<#assign x=3.1415926 /> x:m3小数部分最小3位 #{x;m3}<br>
x:M5小数部分最大5位 #{x;M5}<br>
x:m1M5 #{x;m1M5}<br>
运算结果:3*5=${3*5}<br>
内建int 1.1?int=:${1.1?int}<br> <br>
赋值assign y=20<br> <#assign y=20> 输出数字原:${y?string.number}<br>
输出货币数字:${y?string.currency}<br>
输出百分比:${y?string.percent}<br>
比较大小 21(使用括号): y>21= <#if (y >21) > false <#else> true </#if> <br>
比较大小 21(使用字串):y>21= <#if y gt 21> false <#else> true </#if> <br>
转义字符:${r"< lt <= lte > gt >= gte"} <br>
<hr>
<h2>3.其他处理</h2>
日期: <br>
格式化输出:${date?string('yyyy-MM-dd')}<br>
格式输出yyyy-MM-dd HH:mm:ss zzzz:${date?string("yyyy-MM-dd HH:mm:ss zzzz")}<br>
<hr>
<h2>4.流程控制</h2>
赋值:assign a = '1'<br>
A.if - else逻辑判断<br>
<#assign a = '1'> <#if a='0'> 0 <#elseif a='1'> 1 <#else> 2 </#if> <br>
B.Switch<br> <#switch a> <#case '0'> 0 <#break> <#case '1'> 1 <#break> <#default> 2 </#switch> <br>
C.遍历list<br> 后台传递list:stuList<br>
判断是否为空: <#if stuList?size=0> 空的 <#else> 非空 </#if> <br>
下标: <#list stuList as stu> ${stu_index} </#list><br>
内容: <#list stuList as stu> ${stu.name} </#list><br>
<hr>
<h2>5.集合</h2>
定义list["winter","spring","summer","autumn"]<br>
输出:<#list ["winter","spring","summer","autumn"] as x> ${x} </#list> <br>
list[1..5] <#list 1..5 as list> ${list} </#list> <br>
定义Map{"abc":23,"efg":35}<br>
<#assign ages={"abc":23,"efg":35}> 输出abc的年龄:${ages.abc}<br>
输出efg的年龄:${ages.efg}<br> 定义map,分别输出K-V <#assign selectelement = {"1":"选择A","2":"选择B","3":"选择C", "4":"选择D"}> <#assign skeys=selectelement?keys> <#list skeys as key> <#assign var0="${selectelement[key]}"> ${key}-${selectelement[key]} ---- ${var0} </#list><br>
序列连接["a","b"]+["e","f"]: <#assign liab=["a","b"]+["e","f"]> <#list liab as l > ${l} </#list><br> 散列连接{"1":"a","2":"b"}+{"2":"c","3":"d"}【散列右值覆盖左值】: <#assign
ma={"1":"a","2":"b"}+{"2":"c","3":"d"} > <#assign keys=ma?keys > <#list keys as k> ${ma[k]} </#list><br> 双重list循环<br>
<#list num as list> <#list list as temp> ${temp} </#list> <br> </#list> <br>
<hr>
<h2>6.宏的使用</h2>
A.使用宏 <#macro greet person color> <font size="+2" color="${color}">Hello ${person}!</font> </#macro> <@greet person="ken" color="blue"/> <br>
B.宏调用和嵌套nested:<br> <#macro border msg> ${msg}<br> <#nested><br> repart:<br> <#nested><br> </#macro> <@border msg="The OUT MSG:"> Macro Test! </@border> <br>
C.宏与宏之间的嵌套:<br> <#macro person name> Hello! ${name}<br> </#macro> <@border msg="The OUT MSG:"> <@person name="Ken"/> </@border><br>
D.宏变量中使用循环变量<br> <#macro repeat count> <#list 1..count as x> <#nested x,x/2,x==count /> </#list> </#macro> <@repeat count=4;c,halfc,last> ${c}. ${halfc}<br> <#if last> last! </#if> </@repeat>
</center>
</body>
</html>
3.web.xml文件加入如下代码启动运行
<servlet>
<servlet-name>JspSupportServlet</servlet-name>
<servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
4.struts.xml配置:
<package name="" extends="struts-default" namespace="/">
<action name="loadStudent" class="com.smartsoft.action.StudentAction" method="loadStudent">
<result name="success" type="freemarker">/WEB-INF/flt/student.ftl</result>
</action>
</package>
5.Controller控制类代码:
package com.smartsoft.action;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.smartsoft.model.Student;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class TempHtmlAction extends ActionSupport {
// private static final Logger logger = LogManager.getLogger(GeneHtmlFileAction.class);
private Configuration freemarker_cfg = null;
public String toHtml() {
// TempHtmlService tempHtmlService = ServiceLocator.getTempHtmlrService();
String sGeneFilePath = "";
String sFileName = "student.html";
try {
Map<String, Object> dataMap = getData();
geneHtmlFile("student.ftl", dataMap, sGeneFilePath, sFileName);
} catch (Exception e) {
// logger.error("Index Html Error:" + e.getMessage(), e);
}
return null;
}
/**
* 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取.
*/
protected Configuration getFreeMarkerCFG() {
if (null == freemarker_cfg) {
File templateFile = new File(ServletActionContext.getServletContext().getRealPath("/") + "WEB-INF/flt");
freemarker_cfg = new Configuration();
try {
freemarker_cfg.setDirectoryForTemplateLoading(templateFile);
freemarker_cfg.setDefaultEncoding("UTF-8");
freemarker_cfg.setEncoding(Locale.CHINA, "UTF-8");
} catch (IOException e) {
// logger.error("Get tempalte error", e);
}
}
return freemarker_cfg;
}
public Map<String, Object> getData() {
System.out.println("参数处理...");
Student student = new Student();
student.setId(new Integer(110));
student.setName("Tom");
student.setBirthDate(new Date());
Student student2 = new Student();
student2.setId(new Integer(111));
student2.setName("ken");
student2.setBirthDate(new Date());
List stuList = new ArrayList();
stuList.add(student);
stuList.add(student2);
List indexList = new ArrayList();
indexList.add(new Integer(110));
indexList.add(new Integer(112));
List number = new ArrayList();
number.add(new Integer(1));
number.add(new Integer(2));
number.add(new Integer(3));
List number2 = new ArrayList();
number2.add(new Integer(4));
number2.add(new Integer(5));
number2.add(new Integer(6));
List num = new ArrayList();
num.add(number);
num.add(number2);
Date date = new Date();
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("stuList", stuList);
dataMap.put("msg", " get list success & success! ");
dataMap.put("isExist", Boolean.TRUE);
dataMap.put("date", date);
dataMap.put("num", num);
dataMap.put("indexList", indexList);
System.out.println("结束处理...");
return dataMap;
}
/**
* 生成静态文件.
*
* @param templateFileName
* 模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl"
* @param propMap
* 用于处理模板的属性Object映射
* @param htmlFilePath
* 要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/"
* @param htmlFileName
* 要生成的文件名,例如 "1.htm"
*/
public boolean geneHtmlFile(String templateFileName, Map<String, Object> propMap, String htmlFilePath, String htmlFileName) {
// @todo 从配置中取得要静态文件存放的根路径:需要改为自己的属性类调用
// String sRootDir = "/var/www/ddtank/web";
// String sRootDir = ServletActionContext.getRequest().getRealPath("/webpage");
try {
if (propMap == null) {
propMap = new HashMap<String, Object>();
}
String sRootDir = "e:/webtest/htmlfile";
Template t = getFreeMarkerCFG().getTemplate(templateFileName, "UTF-8");
t.setEncoding("UTF-8");
// 如果根路径存在,则递归创建子目录
creatDirs(sRootDir, htmlFilePath);
File afile = new File(sRootDir + "/" + htmlFilePath + "/" + htmlFileName);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile), "UTF-8"));
t.process(propMap, out);
// ServletContext servletContext = ServletActionContext.getServletContext();
// // data.put("JspTaglibs", new TaglibFactory(servletContext));
// FreemarkerManager freemarkerManager = new FreemarkerManager();
// Configuration configuration = freemarkerManager.getConfiguration(servletContext);
// HttpServletRequest request = ServletActionContext.getRequest();
// HttpServletResponse response = ServletActionContext.getResponse();
// ServletContextHashModel servletContextModel = (ServletContextHashModel) servletContext.getAttribute(".freemarker.Application");
// if (servletContextModel == null) {
// GenericServlet servlet = JspSupportServlet.jspSupportServlet;
// if (servlet != null) {
// servletContextModel = new ServletContextHashModel(servlet, configuration.getObjectWrapper());
// servletContext.setAttribute(".freemarker.Application", servletContextModel);
// TaglibFactory taglibs = new TaglibFactory(servletContext);
// servletContext.setAttribute(".freemarker.JspTaglibs", taglibs);
// }
// }
// HttpRequestHashModel requestModel = (HttpRequestHashModel) request.getAttribute(".freemarker.Request");
// if ((requestModel == null) || (requestModel.getRequest() != request)) {
// requestModel = new HttpRequestHashModel(request, response, configuration.getObjectWrapper());
// request.setAttribute(".freemarker.Request", requestModel);
// }
// propMap.put("Application", servletContextModel);
// propMap.put("Request", requestModel);
// propMap.put("Session", ServletActionContext.getRequest().getSession());
// propMap.put("JspTaglibs", new TaglibFactory(ServletActionContext.getServletContext()));
//
// Template t = getFreeMarkerCFG().getTemplate(templateFileName);
//
// // 如果根路径存在,则递归创建子目录
// creatDirs(sRootDir, htmlFilePath);
// File afile = new File(sRootDir + "/" + htmlFilePath + "/" + htmlFileName);
// Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile), "UTF-8"));
//
// t.process(propMap, out);
// out.flush();
// out.close();
} catch (TemplateException e) {
// logger.error("Error while processing FreeMarker template "
// + templateFileName, e);
e.printStackTrace();
return false;
} catch (IOException e) {
// logger.error("Error while generate Static Html File "
// + htmlFileName, e);
e.printStackTrace();
return false;
}
return true;
}
/**
* 创建多级目录
*
* @param aParentDir
* String
* @param aSubDir
* 以 / 开头
* @return boolean 是否成功
*/
public static boolean creatDirs(String aParentDir, String aSubDir) {
File aFile = new File(aParentDir);
if (!aFile.exists()) {
aFile.mkdirs();
}
File aSubFile = new File(aParentDir + aSubDir);
if (!aSubFile.exists()) {
return aSubFile.mkdirs();
} else {
return true;
}
}
}
6.测试实体类:
package com.smartsoft.model;
import java.io.Serializable;
import java.util.Date;
public class Student implements Serializable {
private Integer id;
private String name;
private Date birthDate;
private String dsc;
private Date birth;
private Integer sex;
//省略get,set
}
以上是最基本的静态化代码流程,配合相关技术便可做出最好的静态化代码了,这里我就不说了