使用应用程序控制器集中检索和调用请求处理组件,如命令和视图。
让我们用例子来讨论应用程序控制器设计模式是如何工作的。
问题
您希望集中并模块化操作和视图管理。
在表示层中,通常在每个请求到达时要做出两个决定:
动因
解决方案
使用应用程序控制器集中检索和调用请求处理组件,如命令和视图。
在表示层中,我们将传入的请求参数映射到特定的请求处理类,并查看处理每个请求的组件。
操作管理是指定位和调用操作来处理特定的请求,而视图管理是指导航和分派到适当的视图或视图生成机制。
结构
我们使用UML类图来表示解决方案的基本结构,本节中的UML序列图展示了解决方案的动态机制。
下面是表示Application Controller模式关系的类图。
类图
序列图
参与者和职责
客户端:调用应用程序控制器。在表示层中,前端控制器或截取过滤器(FrontController or an InterceptingFilter)通常完成此角色。
ApplicationController:使用Mapper将传入请求解析为相应的操作和视图,并将其委托或分派给相应的操作和视图。
映射器( Mapper) :使用Map将传入请求转换为适当的操作和视图。Mapper充当工厂。
map:保存对表示目标资源的句柄的引用。map可以实现为类或注册表。
目标( Target) :有助于完成特定请求的资源,包括命令、视图和样式表。
实施
让我们用一个例子来理解应用程序控制器模式。
步骤1: 让我们创建一些视图组件,如 index.jsp 和 viewstestudent.jsp 页面。
<%@ page language=<font>"java"</font><font> contentType=</font><font>"text/html; charset=ISO-8859-1"</font><font> pageEncoding=</font><font>"ISO-8859-1"</font><font>%> <!DOCTYPE html PUBLIC </font><font>"-//W3C//DTD HTML 4.01 Transitional//EN"</font><font> </font><font>"http://www.w3.org/TR/html4/loose.dtd"</font><font>> <html> <head> <meta http-equiv=</font><font>"Content-Type"</font><font> content=</font><font>"text/html; charset=ISO-8859-1"</font><font>> <title>Index Page</title> </head> <body> <a href=</font><font>"studentView.do?id=10"</font><font>>Show Student Information</a> </body> </html> </font>
步骤2: Application Controller Pattern 是J2EE设计模式,所以让我们创建部署描述符web.xml。
<web-app xmlns:xsi=<font>"http://www.w3.org/2001/XMLSchema-instance"</font><font> xmlns=</font><font>"http://java.sun.com/xml/ns/javaee"</font><font> xsi:schemaLocation=</font><font>"http:</font><font><i>//java.sun.com/xml/ns/javaee </i></font><font> http:</font><font><i>//java.sun.com/xml/ns/javaee/web-app_3_0.xsd" </i></font><font> id=</font><font>"WebApp_ID"</font><font> version=</font><font>"3.0"</font><font>> <display-name>ApplicationControllerWeb</display-name> <servlet> <servlet-name>front</servlet-name> <servlet-<b>class</b>>design.FrontController</servlet-<b>class</b>> </servlet> <servlet-mapping> <servlet-name>front</servlet-name> <url-pattern>*.<b>do</b></url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> </font>
步骤3: 让我们像studentvo.java那样创建Value Object或DTO。
<b>public</b> <b>class</b> StudentVO { <b>private</b> String id; <b>private</b> String name; <font><i>//constructor</i></font><font> <b>public</b> StudentVO(String id, String name) { <b>this</b>.id = id; <b>this</b>.name = name; } </font><font><i>//setters and getters</i></font><font> <b>public</b> String getId() { <b>return</b> id; } <b>public</b> <b>void</b> setId(String id) { <b>this</b>.id = id; } <b>public</b> String getName() { <b>return</b> name; } <b>public</b> <b>void</b> setName(String name) { <b>this</b>.name = name; } } </font>
现在创建 Command 接口。
<b>public</b> <b>interface</b> Command { String execute(RequestContext requestContext); }
实现Command 接口的StudentViewCommand 类
<b>public</b> <b>class</b> StudentViewCommand implements Command { @Override <b>public</b> String execute(RequestContext requestContext) { String id = <b>null</b>; StudentVO studentVo = <b>null</b>; id = requestContext.getParameter(<font>"id"</font><font>); </font><font><i>//call delegate and dao </i></font><font> studentVo = <b>new</b> StudentVO(id, </font><font>"Ramesh"</font><font>); requestContext.setAttribute(</font><font>"student"</font><font>, studentVo); <b>return</b> </font><font>"showStudent"</font><font>; } } </font>
创建 ContextFactory 以处理上下文信息。
<b>import</b> java.util.Map; <b>import</b> javax.servlet.http.HttpServletRequest; <b>public</b> <b>class</b> ContextFactory { <b>public</b> RequestContext getContextObject(HttpServletRequest request) { Map < String, String[] > requestMap = <b>null</b>; RequestContext requestContext = <b>null</b>; HttpRequestMapper requestMapper = <b>null</b>; requestMapper = <b>new</b> HttpRequestMapper(); requestMap = requestMapper.extract(request); requestContext = <b>new</b> RequestContext(request.getRequestURI(), requestMap); <b>return</b> requestContext; } <b>public</b> <b>void</b> bindContextObject(HttpServletRequest request, RequestContext requestContext) { HttpRequestMapper requestMapper = <b>null</b>; requestMapper = <b>new</b> HttpRequestMapper(); requestMapper.bind(request, requestContext.getResponseMap()); } }
让我们创建 RequestContext 类。
<b>import</b> java.util.HashMap; <b>import</b> java.util.Map; <b>public</b> <b>class</b> RequestContext { <b>private</b> String requestUri; <b>private</b> Map < String, String[] > requestMap; <b>private</b> Map < String, Object > responseMap; <b>public</b> RequestContext() { requestUri = <b>null</b>; requestMap = <b>new</b> HashMap < String, String[] > (); responseMap = <b>new</b> HashMap < String, Object > (); } <b>public</b> RequestContext(String requestUri, Map < String, String[] > requestMap) { <b>this</b>.requestUri = requestUri; <b>this</b>.requestMap = requestMap; <b>this</b>.responseMap = <b>new</b> HashMap < String, Object > (); } <b>public</b> String getParameter(String param) { String[] val = <b>null</b>; <b>if</b> (param != <b>null</b>) { val = requestMap.get(param); } <b>return</b> val[0]; } <b>public</b> <b>void</b> setAttribute(String param, Object value) { responseMap.put(param, value); } <b>public</b> String getRequestUri() { <b>return</b> requestUri; } <b>public</b> Map < String, String[] > getRequestMap() { <b>return</b> requestMap; } <b>public</b> Map < String, Object > getResponseMap() { <b>return</b> responseMap; } }
步骤4: 是时候创建frontcontroller.java了。
<b>import</b> javax.servlet.ServletException; <b>import</b> javax.servlet.http.HttpServlet; <b>import</b> javax.servlet.http.HttpServletRequest; <b>import</b> javax.servlet.http.HttpServletResponse; <b>public</b> <b>class</b> FrontController <b>extends</b> HttpServlet { <b>private</b> <b>static</b> <b>final</b> <b>long</b> serialVersionUID = 1 L; @Override <b>protected</b> <b>void</b> service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String page = <b>null</b>; String view = <b>null</b>; Dispatcher dispatcher = <b>null</b>; RequestContext requestContext = <b>null</b>; ContextFactory contextFactory = <b>null</b>; ApplicationController applicationController = <b>null</b>; <font><i>// plubbing code (security, authorization)</i></font><font> </font><font><i>// extracting data from protocol</i></font><font> contextFactory = <b>new</b> ContextFactory(); requestContext = contextFactory.getContextObject(request); applicationController = <b>new</b> ApplicationController(); view = applicationController.process(requestContext); </font><font><i>// binding data back to protocol</i></font><font> contextFactory.bindContextObject(request, requestContext); page = applicationController.mapViewToPage(view); dispatcher = <b>new</b> Dispatcher(); dispatcher.dispatch(request, response, page); } } </font>
步骤5: 创建 ApplicationController 类以及演示此模式所需的各个类。
<b>public</b> <b>class</b> ApplicationController { <b>public</b> String process(RequestContext requestContext) { String view = <b>null</b>; Command command = <b>null</b>; CommandHelper commandHelper = <b>null</b>; commandHelper = <b>new</b> CommandHelper(); command = commandHelper.getCommand(requestContext.getRequestUri()); view = command.execute(requestContext); <b>return</b> view; } <b>public</b> String mapViewToPage(String view) { String page = <b>null</b>; <b>if</b> (view != <b>null</b>) { page = <font>"viewStudent.jsp"</font><font>; } <b>return</b> page; } } </font>
<b>public</b> <b>class</b> CommandHelper { <b>public</b> Command getCommand(String uri) { Command command = <b>null</b>; <b>if</b> (uri.contains(<font>"studentView.do"</font><font>)) { command = <b>new</b> StudentViewCommand(); } <b>return</b> command; } } </font>
<b>public</b> <b>class</b> Dispatcher { <b>public</b> <b>void</b> dispatch(HttpServletRequest request, HttpServletResponse response, String page) { RequestDispatcher rd = <b>null</b>; rd = request.getRequestDispatcher(page); <b>try</b> { rd.forward(request, response); } <b>catch</b> (ServletException e) { e.printStackTrace(); } <b>catch</b> (IOException e) { e.printStackTrace(); } } }
<b>import</b> java.util.Map; <b>import</b> java.util.Set; <b>import</b> javax.servlet.http.HttpServletRequest; <b>public</b> <b>class</b> HttpRequestMapper { <b>public</b> Map < String, String[] > extract(HttpServletRequest request) { Map < String, String[] > requestMap = <b>null</b>; requestMap = request.getParameterMap(); <b>return</b> requestMap; } <b>public</b> <b>void</b> bind(HttpServletRequest request, Map < String, Object > responseMap) { Set < String > keys = <b>null</b>; keys = responseMap.keySet(); <b>for</b> (String param: keys) { request.setAttribute(param, responseMap.get(param)); } } }
输出:
http:<font><i>//localhost:8001/javaT/</i></font><font> http:</font><font><i>//localhost:8001/javaT/studentView.do?id=10</i></font><font> browser : Student Id : 100 Student Name : Ramesh </font>
后果