参考: Java Servlet 技术简介
动作框架,是指编写一个Servlet(请求入口),解析请求的URI得到动作名称,调用处理用户请求的动作类,完成请求访问。当动作执行完毕后,返回一个指向表示结果的JSP的URL(也可以用模板引擎)。
学习过MVC的同学可以在这里一一对应。Servlet通过调用ActionFactory起到路由的作用,处理用户的动作类即是Controller,Controller会调用Model完成任务处理,处理完毕后,返回的URI指向的JSP就是用于表示的View。
大致框架图如下:
在这,会具体把实现动作框架所需部件的功能及构成详细叙述一遍,已达到每一部分都尽量清楚的目的。
“唯一”的Servlet。所有请求的入口,继承自HttpServlet,解析出动作名称,然后通过动作工厂ActionFactory得到具体的动作对象,执行动作的perform
方法,最后转发请求到返回的URL。
示例:
package com.example;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.example.actions.Action;
public class actionServlet extends HttpServlet {
private ActionFactory factory = ActionFactory.getSingleton();
// public void init(ServletConfig config) throws ServletException { ... }
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// 获得动作的名称
String actionName = getActionName(req);
// 通过动作工厂生成actionName的实例对象
Action action = factory.create(actionName);
// 执行动作,得到返回的URL
String url = action.perform(req, res);
// 通过url显示结果
if (url != null)
getServletContext().getRequestDispatcher(url).forward(req, res);
}
// public void destroy() { ... }
private String getActionName(HttpServletRequest req) {
String path = req.getServletPath();
return path.substring(path.lastIndexOf('/'), path.lastIndexOf('.'));
}
}
记录所有动作,通过Servlet发出的动作名称得到动作类,然后对该类实例化,并返回实例对象。
起到存储所有动作、查找指定动作的目的。
示例:
package com.example;
import com.example.actions.*;
import java.util.HashMap;
import java.util.Map;
public class ActionFactory {
private Map actionsMap = defaultMap();
private static ActionFactory singleton;
public static ActionFactory getSingleton() {
if (singleton == null)
singleton = new ActionFactory();
return singleton;
}
public Action create(String actionName) {
Class klass = (Class)map.get(actionName);
if (klass == null) {
throw new RuntimeException(getClass() + " was unable to find an action named '" + actionName + "'.");
}
Action actionInstance = null;
try {
actionInstance = (Action)kalss.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return actionInstance;
}
private Map defaultMap() {
Map map = new HashMap();
map.put("example1", example1Action.class);
map.put("example2", example2Action.class);
// ...
return map;
}
动作类,继承Action接口,完成请求的各项动作。通过调用其他类来完成请求任务,并返回显示结果的jsp的URL。
Action接口
package com.example.actions;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public String perform(HttpServletRequest request, HttpServletResponse response);
}
示例:
package com.example.actions;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// import ...
public class exampleAction implements Action {
@Override
public String perform(HttpServletRequest req, HttpServletResponse res) {
// do something ...
return "/example.jsp"
}
}
配置当某类url到达服务器时,执行哪个servlet。比如,在这里,我们把所有以.perform
为后缀的url都用咱们前面创建的com.example.exampleServlet
来处理。
<web-app>
<servlet>
<servlet-name>exampleservlet-name>
<servlet-class>com.example.exampleServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>exampleservlet-name>
<url-pattern>*.performurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>exampleservlet-name>
<url-pattern>index.htmlurl-pattern>
servlet-mapping>
web-app>