本文主要分三步演示Freemarker这个模版视图的使用:普通Java程序--》Web应用--》与Struts2整合,代替JSP。
一、Freemarker简介
Freemarker是一个非常优秀的模版引擎,这个模版引擎可用于任何场景,FreeMarker负责将数据模型中的数据合并到模版中,从而生成标准输出。
FreeMarker特别适应与MVC模式的Web应用,通常有Java程序准备要显示的数据,由FreeMarker模版引擎来生成页面,而FreeMarker模版则提供页面布局支持,从而能更好地规范MVC架构,保证视图逻辑和业务逻辑分离。
除此之外,FreeMarker也是与Web容器无关的,也就是FreeMarker并不一定要运行在Web容器中;FreeMarker同样应用与非Web应用程序环境。而且,FreeMarker并不是只能生成HTML页面,它也可以生成各种文本,如XML/RTF/Java源代码等。
Struts2可以非常简单地使用FreeMarker模版作为视图技术,对于传统的JSP页面而言,FreeMarker是一个绝佳的替代方案。
除此之外,Struts2默认采用FreeMarker作为其模版文件,而Struts2所有主题模版文件都是采用FreeMarker编写的。因此,如果我们需要扩展Struts2的主题,也需要熟悉FreeMarker技术。
二、Java程序中使用FreeMarker
HelloFreeMarker.java
package com.s2freemarker.exer.test;
import java.io.File;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class HelloFreeMarker {
private Configuration cfg ;
public void init() throws Exception {
cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("src\\com\\s2freemarker\\exer\\templates"));
}
public void process() throws Exception{
Map<Object,Object> root = new HashMap<Object,Object>();
root.put("name", "FreeMarker");
root.put("msg", "First example for freemarker .");
Template t = cfg.getTemplate("test.ftl");
t.process(root, new OutputStreamWriter(System.out));
}
/**
* @param args
*/
public static void main(String[] args) throws Exception{
HelloFreeMarker hfm = new HelloFreeMarker();
hfm.init();
hfm.process();
}
}
模版文件test.ftl:
${name},hello!${msg}
三、Web应用中使用FreeMarker
HTML模版test.ftl:
<html> <head><title>FreeMarker</title></head> <body> ${message} </body> </html>
Servlet——FreemarkerServlet:
package com.s2freemarker.exer.web.servlet;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class FreemarkerServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 5495454566664178949L;
private Configuration config;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<Object , Object> root = new HashMap<Object,Object>();
root.put("message", "Hello FreeMarker");
Template t = config.getTemplate("test.ftl");
response.setContentType("text/html;charset="+t.getEncoding());
Writer out = response.getWriter();
try {
t.process(root, out);
} catch (TemplateException e) {
throw new ServletException("Handle template error !",e);
}
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
config = new Configuration();
//the method of loading template in the servlet Configuration.setServletContextForTemplateLoading()
config.setServletContextForTemplateLoading(getServletContext(), "WEB-INF\\templates");
}
}
四、整合Struts2
index.jsp:
<%@ page language="java" contentType="text/html;charset=UTF-8"%> <%@ page session="false" %> <% response.sendRedirect(request.getContextPath()+"/freemarker_index.action"); %>
在FreeMarker模版中增加标签库定义后,就可以在FreeMarker模版中使用Struts2标签了。(<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"]>)
将Struts2核心jar包下的struts-tags.tld文件复制到WEB-INF路径下。
在web.xml中启动JspSupportServlet。
HTML模版test2.ftl:
<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"]> <html> <head><title>Struts2 FreeMarker</title></head> <body> <@s.form action="login.action"> <@s.textfield name="uid" label="USRNAME"/> <@s.textfield name="password" label="PASSWORD"/> <@s.submit value="login"/> </@s.form> </body> </html>
welcome.ftl:
<html> <head><title>welcome page</title></head> <body> Welcome , ${uid}, you have loged in . </body> </html>
Action——FreemarkerAction:
package com.s2freemarker.exer.web.actions;
import com.opensymphony.xwork2.ActionSupport;
public class FreemarkerAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 4684751322790860946L;
private String uid ;
private String password ;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String login() throws Exception{
return SUCCESS;
}
}
五、servlet和action所需配置文件web.xml/struts.xml
struts.xml:
将FreeMarkerz作为视图结果时要将resultType设置为freemarker。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="freemarker" extends="struts-default" > <action name="FreemarkerServlet"> <result>/servlet/FreemarkerServlet</result> </action> <action name="freemarker_index"> <result type="freemarker">/WEB-INF/templates/test2.ftl</result> </action> <action name="login" class="com.s2freemarker.exer.web.actions.FreemarkerAction" method="login"> <result type="freemarker">/WEB-INF/templates/welcome.ftl</result> </action> </package> </struts>
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>JspSupportServlet</servlet-name> <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>FreemarkerServlet</servlet-name> <servlet-class>com.s2freemarker.exer.web.servlet.FreemarkerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FreemarkerServlet</servlet-name> <url-pattern>/servlet/FreemarkerServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>