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包下新建如下文件:
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文件
Freemaker Servlet Application
guestbook
com.shiryu.freeServlet.controller.GuestbookServlet
guestbook
*.a
4.以下是前webroot / template下的ftl文件:
<#macro page title>
FreeMarker Example Web Application 2 - ${title?html}
${title?html}
<#nested>
FreeMarker Example 2
#macro>
index.ftl<#import "/lib/common.ftl" as com>
<#escape x as x?html>
<@com.page title="Index">
Add new message | How this works?
<#if guestbooks?size = 0>
No messages.
<#else>
The messages are:
Name
Message
<#list guestbooks as e>
${e.name} <#if e.email?length != 0> (${e.email})#if>
${e.message}
#list>
#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>
Please correct the following problems:
<#list errors as e>
- ${e}
#list>
#if>
Back to the index page
@com.page>
#escape>
add.ftl
<#import "/lib/common.ftl" as com>
<#escape x as x?html>
<@com.page title="Entry added">
You have added the following entry to the guestbook:
Name: ${entry.name}
<#if entry.email?length != 0>
Email: ${entry.email}
#if>
Message: ${entry.message}
Back to the index page...
@com.page>
#escape>