总体目录结构如下:
搭建完成后,效果和示例二是一样的。
1.新建项目FreemakerS ,将freemaker.jar 拷入lib下;
2.在新建com.shiryu.freeServlet.model包里新建以下文件:
实体类Guestbook.java
package com.shiryu.freeServlet.model;
public class Guestbook {
private String name;
private String email;
private String message;
public Guestbook(String name, String email, String message) {
this.name = name;
this.email = email;
this.message = message;
}
public String getEmail() {
return email;
}
public String getMessage() {
return message;
}
public String getName() {
return name;
}
}
Page.java
//用来传递模板文件template或则是跳转forword
package com.shiryu.freeServlet.model;
import java.util.*;
public class Page {
private String template;
private String forward;
private Map root = new HashMap();
//put具有四种形态,形参不同类型
public void put(String name,Object value){
root.put(name, value);
}
public void put(String name,int value){
root.put(name, value);
}
public void put(String name,double value){
root.put(name, value);
}
public void put(String name,boolean value){
root.put(name, value);
}
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
forward=null;
this.template = template;
}
public String getForward() {
return forward;
}
public void setForward(String forward) {
template = null;
this.forward = forward;
}
public Map getRoot() {
return root;
}
}
2.在新建com.shiryu.freeServlet.controller包下新建如下文件:
ControllerServlet.java
package com.shiryu.freeServlet.controller;
import java.io.*;
import java.lang.reflect.*;
import java.util.Locale;
import javax.servlet.*;
import javax.servlet.http.*;
import com.shiryu.freeServlet.model.Page;
import freemarker.template.*;
public class ControllerServlet extends HttpServlet {
private static final long serialVersionUID = 2621960985463765229L;
private Configuration cfg;
public void init() {
// 创建一个freemaker.template包中的configrution对象
cfg = new Configuration();
// 得到模板文件所在路径
cfg.setServletContextForTemplateLoading(getServletContext(),"templates");
// 将update dealy设置为0方便测试
cfg.setTemplateUpdateDelay(0);
// 在html错误被打印出来
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
// 使用beans封装应用
cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
cfg.setDefaultEncoding("UTF-8");
cfg.setOutputEncoding("UTF-8");
cfg.setLocale(Locale.getDefault());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 对action进行选择
String action = req.getServletPath();
if (action == null)
action = "index";
if (action.startsWith("/"))
//语法strVariable.substring(start, end)
//substring(int i)他的意思是从字符串的索引值为i开始截取(获得)字符串
action = action.substring(1);
//int lastIndexOf(int ch, int fromIndex)
//从指定的索引处开始进行后向搜索,返回最后一次出现的指定字符在此字符串中的索引。
if (action.lastIndexOf(".") != -1) {
action = action.substring(0, action.lastIndexOf("."));
}
Method actionMethod = null;
//得到当前运行时对象所属的类对象,返回类对象的一个方法
//参数为此方法的名称字符串及所需参数的类对象类型数组
try {
actionMethod = getClass().getMethod(action + "Action", new Class[] { HttpServletRequest.class, Page.class });
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
req.setCharacterEncoding(cfg.getOutputEncoding());
Page page = new Page();
try {
//方法调用,当前的对象数组
//例如:
//Class[] a=new Class[]{String[].class};
//Object[] b=new Object[]{new String[0]};
// 生成2个新的数组,第一个数组里存的是Class类型,第二个存放的是Object类型.
actionMethod.invoke(this, new Object[] { req, page });
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// 如果从page获得了template,进行页面输出
if (page.getTemplate() != null) {
Template t = cfg.getTemplate(page.getTemplate());
resp.setContentType("text/html; charset=" + cfg.getOutputEncoding());
resp.setHeader("Cache-Control","no-store,no-cache,must-revalidate," + "post-check=0,
pre-check=0");
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Expires", "Thu, 01 Dec 2010 00:00:00 GMT");
Writer out = resp.getWriter();
try {
t.process(page.getRoot(), out);
} catch (TemplateException e) {
e.printStackTrace();
}
}
// 如果page的指向不为空
else if (page.getForward() != null) {
RequestDispatcher rd = req.getRequestDispatcher(page.getForward());
rd.forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
GuestbookServlet.java
package com.shiryu.freeServlet.controller;
import java.io.IOException;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import com.shiryu.freeServlet.model.*;
public class GuestbookServlet extends ControllerServlet {
private static final long serialVersionUID = 1385738680025723760L;
@SuppressWarnings("unchecked")
private ArrayList guestbooks = new ArrayList();
//各个action及其业务逻辑
@SuppressWarnings("unchecked")
public void indexAction(HttpServletRequest req, Page p) {
List snapShot;
synchronized (guestbooks) {
snapShot = (List) guestbooks.clone();
}
p.put("guestbooks", snapShot);
p.setTemplate("index.ftl");
}
@SuppressWarnings("unchecked")
public void formAction(HttpServletRequest req, Page p) throws IOException,
ServletException {
p.put("name", noNull(req.getParameter("name")));
p.put("email", noNull(req.getParameter("email")));
p.put("message", noNull(req.getParameter("message")));
List errors = (List) req.getAttribute("errors");
p.put("errors", errors == null ? new ArrayList() : errors);
p.setTemplate("form.ftl");
}
@SuppressWarnings("unchecked")
public void addAction(HttpServletRequest req, Page p) throws IOException,
ServletException {
List errors = new ArrayList();
String name = req.getParameter("name");
String email = req.getParameter("email");
String message = req.getParameter("message");
if (isBlank(name)) {
errors.add("please enter your name");
}
if (isBlank(message)) {
errors.add("please enter your message");
}
if (errors.isEmpty()) {
if (email == null)
email = "";
Guestbook book = new Guestbook(name.trim(), email.trim(), message);
synchronized (guestbooks) {
guestbooks.add(0, book);
}
p.put("entry", book);
p.setTemplate("add.ftl");
}else{
req.setAttribute("errors", errors);
p.setForward("form.a");
}
}
public static String noNull(String s) {
return s == null ? "" : s;
}
public static boolean isBlank(String s) {
return s == null || s.trim().length() == 0;
}
}
3.编辑
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Freemaker Servlet Application</display-name>
<servlet>
<servlet-name>guestbook</servlet-name>
<servlet-class>com.shiryu.freeServlet.controller.GuestbookServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>guestbook</servlet-name>
<url-pattern>*.a</url-pattern>
</servlet-mapping>
</web-app>
4.以下是前webroot / template下的ftl文件:
lib下
common.ftl
<#macro page title>
<html>
<head>
<title>FreeMarker Example Web Application 2 - ${title?html}</title>
<meta http-equiv="Content-type" content="text/html; charset=${.output_encoding}">
</head>
<body>
<h1>${title?html}</h1>
<hr>
<#nested>
<hr>
<table border="0" cellspacing=0 cellpadding=0 width="100%">
<tr valign="middle">
<td align="left">
<i>FreeMarker Example 2</i>
<td align="right">
<a href="http://freemarker.org"><img src="poweredby_ffffff.png" border=0></a>
</table>
</body>
</html>
</#macro>
index.ftl
<#import "/lib/common.ftl" as com>
<#escape x as x?html>
<@com.page title="Index">
<a href="form.a">Add new message</a> | <a href="help.html">How this works?</a>
<#if guestbooks?size = 0>
<p>No messages.
<#else>
<p>The messages are:
<table border=0 cellspacing=2 cellpadding=2 width="100%">
<tr align=center valign=top>
<th bgcolor="#C0C0C0">Name
<th bgcolor="#C0C0C0">Message
<#list guestbooks as e>
<tr align=left valign=top>
<td bgcolor="#E0E0E0">${e.name} <#if e.email?length != 0> (<a href="mailto:${e.email}">${e.email}</a>)</#if>
<td bgcolor="#E0E0E0">${e.message}
</#list>
</table>
</#if>
</@com.page>
</#escape>
form.ftl
<#import "/lib/common.ftl" as com>
<#escape x as x?html>
<@com.page title="Add Entry">
<!- - 错误的输出 - ->
<#if errors?size != 0>
<p><font color=red>Please correct the following problems:</font>
<ul>
<#list errors as e>
<li><font color=red>${e}</font>
</#list>
</ul>
</#if>
<form method="post" action="add.a">
Your name: <input type="text" name="name" value="${name}" size=51><br>
Your e-mail (optional): <input type="text" name="email" value="${email}" size=40><br>
Message:<br>
<textarea name="message" wrap="soft" rows=3 cols=50>${message}</textarea><br>
<input type="submit" value="Submit">
</form>
<p><a href="index.a">Back to the index page</a>
</@com.page>
</#escape>
add.ftl
<#import "/lib/common.ftl" as com>
<#escape x as x?html>
<@com.page title="Entry added">
<p>You have added the following entry to the guestbook:
<p><b>Name:</b> ${entry.name}
<#if entry.email?length != 0>
<p><b>Email:</b> ${entry.email}
</#if>
<p><b>Message:</b> ${entry.message}
<p><a href="index.a">Back to the index page...</a>
</@com.page>
</#escape>