前端控制器模式

原创 2003年05月28日 09:01:00

前端控制器处理所有从用户过来的请求。所有用户的请求都要通过前端控制器,只有在得到控制器验证后,被前端控制器重新定向才可以访问相应的资源。这是安全控制的一种方式。实际上在,在J2EE体系结构下,各种资源的联结都是通过XML实现的,所有web层应用的文件要部署时候必须打包成war文件,web文件通常是一些jsp文件,也有一些servlet和 javabean以及jsp标签。在简单的WEB应用中,可以在jsp文件中实现对业务方法,甚至后台数据库资源等实现直接访问。但是作为一个可扩展和可伸缩的应用来说,这样做有很多不便。这在MVC模式分析与应用时我会有更详实的论证。这里要集中研究的是前端控制器模式在应用中是怎么实现的。先来看看Front Control 的类图[i]<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />CSDN_Dev_Image_2003-5-272211310.png

   任何模式都有应用的上下文环境(context),在前端控制器模式的应用环境可以分布式的处理,图中控制器虽然只有一个,实际中有可能是多个控制器分布式地来处理不同的控制要求。这种分布式控制机制是由WEB的配置文件web.xml来实现的。当然也可以集中处理所有请求,在一个集中的环境中判断分发请求。可以实现一个链式的结构。这其实就是GOF中提的Chain of Responsibility模式了,进一步映射到J2EE模式目录中,严格的讲在控制前面我们应该采取过滤器模式,这样前端的验证可以得到更好的处理,但是这样阶梯的处理容易造成低效率。因为判断链的方式需要花费时间。前面说过分布式控制用户的请求是由配置文件描述的,下面是我开发的一个事例程序中的WEB配置文件:

1<web-app>

2 <servlet>

 3  <servlet-name>logincheck</servlet-name>

 4  <servlet-class>frontcontrolleraa.logincheck</servlet-class>

 5 </servlet>

 6 <servlet-mapping>

 7   <servlet-name>logincheck</servlet-name>

 8  <url-pattern>/logincheck</url-pattern>

 9 </servlet-mapping>

 10 <servlet>

 11   <servlet-name>loginfront</servlet-name>

 12   <jsp-file>/login.jsp</jsp-file>

 13 </servlet>

 14 <servlet-mapping>

 15   <servlet-name>loginfront</servlet-name>

 16   <url-pattern>/test/*</url-pattern>

17 </servlet-mapping>

18</web-app>

当有客户端请求时,容器都要读取配置文件以便判断用户对资源的访问权限,并对某些类型的用户分发到对应的控制器来处理。应用中16行意思是规定在上下文环境下(开发目录)的子目录下test下的所有文件必须交给一个名字叫loginfront的servlet来处理。在11行中把这个servlet映射到了一个jsp文件(大家知道jsp本质上是servlet)。在login.jsp文件其实只是一个用户界面,他把获取的请求交给名为logincheck的servlet(在配置中应有相应的描述)判断——典型的视图(jsp实现)-控制器(servlet实现)模式(<form method="post" action="/test/logincheck">)。这样就实现了对test目录下资源的保护。很显然一个保护天平的一端是实现了对整个被访问资源的保护,另一端则是对某个资源进行了保护,实现了控制访问。这种保护方式对于在每个资源中加入控制机制要可扩展的多,在用户角色改变时,代码也根本不要做改变,所做的工作只是要改变配置文件而已。代码的维护变得相对独立,在开发业务逻辑的代码时候尤其重要,因为我们不需要牵涉到其他的事情了而集中处理业务逻辑。当然控制器的实现可以有多种策略,这里采用的是servlet策略。核心代码如下:

package frontcontrolleraa;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

 

public class logincheck extends HttpServlet {

  static final private String CONTENT_TYPE = "text/html; charset=GBK";

  //Initialize global variables

  public void init() throws ServletException {

  }

  //Process the HTTP Get request

  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    //用doPost服务

    doPost(request,response);

 

  }

 

  //Process the HTTP Post request

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    response.setContentType(CONTENT_TYPE);

 

    //得到用户名和密码

    String id;

    String passwd;

    id=request.getParameter("userName").trim();

    passwd=request.getParameter("password").trim();

 

    /*

判断用户和密码合法性和效用(决定可以访问的资源Dispatcher View

      在此处如果逻辑更多,可以交由Help处理(Help view模式),可以分发到其他控器验证(Intercepting Filter)。

 

由于只是演示前端控制器的使用,故此处不用数据库:)

*/

    if(id.equals("angus_han")&&passwd.equals("hanchen")){

      //合法,转向到可用页面

      response.sendRedirect("other.jsp");

    }

    else

      //非法,转向到错误页面,实际应用中也可以直接再次转到登陆页面

      //就是说只要简单地返回就可以了

      response.sendRedirect("loginErrorPage.jsp");

    PrintWriter out = response.getWriter();

    out.println("<html>");

    out.println("<head><title>logincheck</title></head>");

    out.println("<body>");

    out.println("<p>The servlet has received a POST. This is the reply.</p>");

    out.println("</body></html>");

  }

  //Clean up resources

  public void destroy() {

  }

}

关于代码的解释在上面已经也很多注释了,这里就不多做解释了。当然在简单的应用中控制器也可以使用jsp实现,复杂的应用则常结合视图助手(View Helper),过滤器(Intercepting Filter),分发者(Dispatcher View)模式应用。[ii]

再来讨论上面描[A1] 反例(一个在一些页面缺乏用户认证的网上找到的商业系统,在这里就不点名了),显然程序开发者注意到了资源的保护,退一步说在一个商业应用中不考虑安全的资源保护简直让人感到毛骨悚然!但是开发者只在部分页面中加入了判断逻辑,这种方式至少有两个缺陷:

首先,代码耦合性强

其次,安全性低

   前一个缺陷导致重复的代码,在大量需要保护的页面中加入类似的判断逻辑,在增加业务代码时候也必须考虑到加入本来不需要的判断逻辑,前一个缺陷也导致了代码的维护变得量大而难以扩展,尤其在需要调整大量保护资源类别时,维护者不得不(简直是被迫)深入到每个业务代码中去,然而在使用了web.xml后这种耦合骤然降低为0;

   后一种缺陷导致开发者挂一漏万,一不小心就会“忘掉”还有个判断逻辑,有如江堤之蚁穴,“周密”的考虑功亏一篑。在反例中只要知道资源的绝对域名,就可以通过浏览器访问相应的资源(当然有代码保护的页面例外)。但是在此演示中我们可以看到,只要试图访问test子目录下的资源,任何资源,浏览器中都会被重新定位到登陆页面。就是说除非你首先登陆,否则客户端有任何资源请求都应该重新定位到登陆页面,要求用户注册或登陆以便获得相应资源的访问权限。当然,这些安全处理的抽象实现要求在servlet规范[iii]中有明确要求,更详细的多控制器处理也可以参照规范编写。示例代码在WebLogic Server ,Jboss,Apusic调试下全部通过。结果表明他们都对这种规范要求的机制支持的很好。



[ii],  http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html

在《Core J2EE Patterns》中也有关于控制器实现策略的Sample Code

[iii],  Servlet-2_3-fcs-spec规范75


 [A1]演示?中

J2EE 中的几种常用模式?及对设计模式的一些看 法

Session Facade Pattern:使用 SessionBean 访问 EntityBean; Message Facade Pattern:实现异步调用; EJB Command Pa...
  • uniquewonderq
  • uniquewonderq
  • 2015年06月09日 20:53
  • 1454

前端控制器和页面控制器

MVC也不是一成不变的,一种稍微有些不同的MVC实现已经通过一些框架,譬如Microsoft的ASP.NET,流行起来了。在这种MVC中,并不是令分发器去寻找一个控制器并执行之,而是直接到达视图并且在...
  • jbjwpzyl3611421
  • jbjwpzyl3611421
  • 2014年01月24日 10:37
  • 2625

设计模式学习笔记--前端控制器模式

三十、前端控制器模式前端控制器模式(Front Controller Pattern),主要用于集中统一化对外的请求接口,便于更好的封装内部逻辑。实现创建不同的View视图类HomeView,Stud...
  • binglumeng
  • binglumeng
  • 2016年12月12日 18:43
  • 1108

前端控制器模式

前端控制器处理所有从用户过来的请求。所有用户的请求都要通过前端控制器,只有在得到控制器验证后,被前端控制器重新定向才可以访问相应的资源。这是安全控制的一种方式。实际上在,在J2EE体系结构下,各种资...
  • cx0998
  • cx0998
  • 2003年05月28日 09:01
  • 4821

MVC页面不同控制器下的方法调用同一个后台函数

尤其是在多语言开发当中,切换语言的时候很有用。关键点就是要找到路径。 比如,我有个_LoginPartial.cshtml,这个页面是网页的公用部分,自己开发的网站,每个页面都会加载这一部分内容。 ...
  • liuxufeiyang000
  • liuxufeiyang000
  • 2015年11月24日 10:57
  • 2197

前端控制器设计模式

前端控制器设计模式       前端控制器(front controller)主要提供一种可以集中式管理请求的控制器,一个前端控制器可以接受所有的客户请求,将每个请求递交给相应的请求...
  • xuchuangqi
  • xuchuangqi
  • 2016年11月02日 23:45
  • 642

Java设计模式(3):前端控制器模式

前端控制器模式(Front Controller Pattern)提供一种可以集中管理请求的控制器,即所谓的前端控制器,该前端控制器用于响应客户请求,为每个请求寻找匹配的处理器。在这种模式中,控制器提...
  • bwf_erg
  • bwf_erg
  • 2017年05月03日 19:40
  • 272

前端控制器模式-设计模式

前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请...
  • ayw255
  • ayw255
  • 2016年11月04日 17:04
  • 176

前端控制器模式

前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请...
  • qq_38131668
  • qq_38131668
  • 2018年02月14日 10:01
  • 5

JAVA 开发平台的技术和框架(二)前端控制器:Struts2 ,Spring MVC

前端控制器:Struts2 ,Spring MVC 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响...
  • liushuicike
  • liushuicike
  • 2015年03月20日 13:17
  • 2118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:前端控制器模式
举报原因:
原因补充:

(最多只允许输入30个字)