<SCRIPT type=text/javascript><!--google_ad_client = "pub-9750319131714390";google_ad_width = 160;google_ad_height = 600;google_ad_format = "160x600_as";google_ad_type = "text_image";google_ad_channel = "";//--> </SCRIPT><SCRIPT src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript></SCRIPT> | Model 2 架構將應用程式的Web 層區分為Controller、Model與View三個角色,使用JSP/Servlet技術,可以很適切的實現這個架構。 Model 2架构将应用程式的Web层区分为Controller、Model与View三个角色,使用JSP/Servlet技术,可以很适切的实现这个架构。
JSP/Servlet對於Model 2架構的實現對應分別為: JSP/Servlet对于Model 2架构的实现对应分别为:
- Servlet 實現Controller 角色 Servlet实现Controller角色
- JavaBean或其它自訂值物件實現Model 角色 JavaBean或其它自订值物件实现Model角色
- 沒有程式邏輯的JSP 實現View 角色 没有程式逻辑的JSP实现View角色
首先使用Servlet來實現一個簡單的控制器,在這之前,您需要先瞭解Command 模式 。 首先使用Servlet来实现一个简单的控制器,在这之前,您需要先了解Command模式 。 使用Command 模式,可以使控制器的實現更具彈性,不過作為一個範例,這邊僅實作出概念,因而接下來會簡化一些實作內容。 使用Command模式,可以使控制器的实现更具弹性,不过作为一个范例,这边仅实作出概念,因而接下来会简化一些实作内容。
首先,實作Command 模式中實際執行請求的物件,先定義一個IAction介面: 首先,实作Command模式中实际执行请求的物件,先定义一个IAction介面:
package onlyfun.caterpillar; package onlyfun.caterpillar;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
public interface IAction { public interface IAction { public void execute(HttpServletRequest req, public void execute(HttpServletRequest req, HttpServletResponse res); HttpServletResponse res); } 真正執行客戶端請求的物件必須實作IAction 介面,具體要實作的Action留在下一個主題,先來看看如何實現Command 模式中的Invoker類: 真正执行客户端请求的物件必须实作IAction介面,具体要实作的Action留在下一个主题,先来看看如何实现Command模式中的Invoker类:
package onlyfun.caterpillar; package onlyfun.caterpillar;
import java.io.IOException; import java.io.IOException; import java.util.*; import java.util.*; import javax.servlet.RequestDispatcher; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
public class Invoker { public class Invoker { private Map actions; private Map actions;
private String defaultPage; private String defaultPage;
public Invoker() { public Invoker() { actions = new HashMap(); actions = new HashMap(); }
public void addCommand(String actionName, public void addCommand(String actionName, IAction action) { IAction action) { actions.put(actionName, action); actions.put(actionName, action); }
public void request(HttpServletRequest req, public void request(HttpServletRequest req, HttpServletResponse res) HttpServletResponse res) throws ServletException, IOException { throws ServletException, IOException { IAction action = IAction action = (IAction) actions.get(req.getServletPath()); (IAction) actions.get(req.getServletPath());
if(action != null) { if(action != null) { action.execute(req, res); action.execute(req, res); } else { else { RequestDispatcher dispatcher = RequestDispatcher dispatcher = req.getRequestDispatcher(defaultPage); dispatcher.forward(req, res); dispatcher.forward(req, res); } }
public String getDefaultPage() { public String getDefaultPage() { return defaultPage; return defaultPage; }
public void setDefaultPage(String defaultPage) { public void setDefaultPage(String defaultPage) { this.defaultPage = defaultPage; this.defaultPage = defaultPage; } } 這是一個很簡單的控制轉發類,這個類將根據客戶端請求的Servlet路徑來瞭解實際該調用的Action物件,如果找不到,則轉發至預設的頁面。 这是一个很简单的控制转发类,这个类将根据客户端请求的Servlet路径来了解实际该调用的Action物件,如果找不到,则转发至预设的页面。
接下來在Controller 中使用Invoker 類,Controller 使用Servlet 來實現: 接下来在Controller中使用Invoker类,Controller使用Servlet来实现:
package onlyfun.caterpillar; package onlyfun.caterpillar;
import java.io.*; import java.io.*; import javax.servlet.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.http.*;
public class DispatcherServlet extends HttpServlet { public class DispatcherServlet extends HttpServlet { private Invoker invoker; private Invoker invoker;
public void init() throws ServletException { public void init() throws ServletException { invoker = new Invoker(); invoker = new Invoker(); invoker.addCommand("/welcome.action", new WelcomeAction()); new WelcomeAction()); invoker.addCommand("/login.action", new LoginAction()); new LoginAction()); invoker.setDefaultPage("/welcome.action"); }
public void doPost(HttpServletRequest req, public void doPost(HttpServletRequest req, HttpServletResponse res) HttpServletResponse res) throws ServletException, IOException { throws ServletException, IOException { invoker.request(req, res); invoker.request(req, res); } public void doGet(HttpServletRequest req, public void doGet(HttpServletRequest req, HttpServletResponse res) HttpServletResponse res) throws ServletException, IOException { throws ServletException, IOException { doPost(req, res); doPost(req, res); } } 為了簡化程式以方便說明,直接將可用的請求路徑寫在init()中,目前只有兩個可用的請求路徑,實際上設計時,這個部份該可以在屬性檔案中設定,以這個Model 2架構的程式更有彈性而可以重用。 为了简化程式以方便说明,直接将可用的请求路径写在init()中,目前只有两个可用的请求路径,实际上设计时,这个部份该可以在属性档案中设定,以这个Model 2架构的程式更有弹性而可以重用。
這邊實現Model 2架構的方式將採用前端控制器(Front Controller)模式,客戶端所有的請求將透過上面這個DispatcherServlet,在web.xml中可以這麼設定來達到目的: 这边实现Model 2架构的方式将采用前端控制器(Front Controller)模式,客户端所有的请求将透过上面这个DispatcherServlet,在web.xml中可以这么设定来达到目的:
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<description> Model 2 Example Model 2 Example </description> <display-name>Model 2 Examples</display-name> <display-name>Model 2 Examples</display-name>
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> onlyfun.caterpillar.DispatcherServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
</web-app> 按照這個web.xml的設定,所有以*.action結尾的請求都將由DispatcherServlet來處理。 按照这个web.xml的设定,所有以*.action结尾的请求都将由DispatcherServlet来处理。 |