J2EE设计模式浅谈(二)之Filter

                                                         J2EE设计模式浅谈(二)之Filter
                                                                                               J雪(zhuam) Email:zhaum@studyjava.com

其实J2EE中太多的定义是很烦人的,设计模式也很抽象的,今天我就以Servlet2.3中新增的Filter在Web Application中的应用,来进一步的说明设计模式。
首先假设我们现在想做一个Web Application(例如BBS)。
要求具备下列功能:
1、 在用户发帖子之前,要进行身份认证,以确认该用户是已登陆用户。
2、 其次是要对删除帖子,修改帖子,进行权限检查。
3、 访问特定资源(Web 页、JSP 页)时的身份认证
那么对待这些要求我们该怎么去做,如果在每个页面中都写检查权限的代码,不是一个好想法,且使的程序的可重用性降低,对比设计模式Intercepting Filter(截获过滤)正好符合我们的要求,且在Servlet2.3中通过使用过滤器(Filter)能够使得Web Application开发者能够在请求到达Web资源之前截取请求,在处理请求之后修改应答。
一个执行过滤器的Java 类必须实现javax.servlet.Filter 接口。这一接口含有三个方法:
· init(FilterConfig):这是容器所调用的初始化方法。它保证了在第一次 doFilter() 调用前由容器调用。它能获取在 web.xml 文件中指定的filter初始化参数(文章的后面有lightningboard 的web.xml文件)。 
· doFilter(ServletRequest, ServletResponse, FilterChain):这是一个完成过滤行为的方法。它同样是上一个过滤器调用的方法。引入的 FilterChain 对象提供了后续过滤器所要调用的信息,Filter中因为有了 FilterChain,就使的几个FILTER 成了一个链条。 
· destroy():容器在销毁过滤器实例前,doFilter()中的所有活动都被该实例终止后,调用该方法
在开源的lightningboard BBS中实现了两个Filter,如下
1、ControllerFilter在这里起到的是Front Controller(前端控制器)的作用,是MVC模式中的控制器,是该BBS的入口点。
package lightningboard;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lightningboard.action.*;

/**
 * Control all *.do.
 * @version 0.3.5
 * @author Xiaobo Liu
 */
public class ControllerFilter implements Filter {

  /**
   * Action dispatch
   * example: homde.do will be create HomeAction and call its excute() method.
   */
  protected FilterConfig filterConfig;

  public void init(FilterConfig config) {
    this.filterConfig = config;
  }

  public void destroy() {
    this.filterConfig = null;
  }
  public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
      throws IOException, ServletException{
    HttpServletRequest request = (HttpServletRequest)srequest;
    HttpServletResponse response = (HttpServletResponse)sresponse;

    long timeStart=System.currentTimeMillis();

    Configuration cfg=Configuration.getInstance();
    String encoding=cfg.getValue("SYS.ENCODING");
    request.setCharacterEncoding(encoding);

    String path = (String) request.getRequestURI();
    String actionString = path.substring(path.lastIndexOf("/") + 1,path.lastIndexOf("."));
    String forwardPage=null;
    try {
      if(actionString.equals("forum"))
        forwardPage=new ForumAction().excute(request,response);
      else if(actionString.equals("topic"))
        forwardPage=new TopicAction().excute(request,response);
      else if(actionString.equals("user"))
        forwardPage=new UserAction().excute(request,response);
      else if(actionString.equals("userList"))
        forwardPage=new UserListAction().excute(request,response);
      else if(actionString.equals("login"))
        forwardPage=new LoginAction().excute(request,response);
      else if(actionString.equals("register"))
        forwardPage=new RegisterAction().excute(request,response);
      else if(actionString.equals("post"))
        forwardPage=new PostAction().excute(request,response);
      else if(actionString.equals("postP"))
        forwardPage=new PostPAction().excute(request,response);
      else if(actionString.equals("userEdit"))
        forwardPage=new UserEditAction().excute(request,response);
      else if(actionString.equals("userEditP"))
        forwardPage=new UserEditPAction().excute(request,response);
      else if(actionString.equals("logout"))
        forwardPage=new LogoutAction().excute(request,response);
      else //default: home
        forwardPage=new HomeAction().excute(request,response);
    }catch (ActionException ex) {
      Debug.out(ex);
      request.setAttribute("actionMessage",new ActionMessage("system_error"));
      forwardPage="/actionMessage.jsp";
    }
    // forward page
    if (forwardPage!=null){
      String processTime=""+(System.currentTimeMillis()-timeStart);
      request.setAttribute("processTime",processTime);
      filterConfig.getServletContext().getRequestDispatcher(forwardPage).forward(request,response);
    }
  }
}

2、此FILTER起的是Intercepting Filter(截获过滤)的作用。
package lightningboard.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionAuthorizationFilter implements Filter {
  protected FilterConfig filterConfig;

  public void init(FilterConfig config) {
    this.filterConfig = config;
  }

  public void destroy() {
    this.filterConfig = null;
  }


  private boolean passed(ServletRequest request, ServletResponse response)
      throws IOException, ServletException {
    boolean result=false;
    String objectName=this.filterConfig.getInitParameter("OBJECT_NAME");
    HttpServletRequest req = (HttpServletRequest)request;
    HttpSession session =req.getSession(false);
    if(session!=null){
      Object object=session.getAttribute(objectName);
      if(object!=null)
        result= true;
    }
      return result;
  }

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
      throws IOException, ServletException{
    if (passed(request,response))
        filterChain.doFilter(request, response);
    else{
      HttpServletResponse res = (HttpServletResponse)response;
      String errorPage=this.filterConfig.getInitParameter("ERROR_PAGE");
      res.sendRedirect(errorPage);
    }
  }
}
容器通过 Web 应用程序中的配置描述符 web.xml 文件解析过滤器配置信息。有两个新的标记与过滤器相关:  和  。  标记是一个过滤器定义,它必定有一个   和   子元素。  子元素给出了一个与过滤器实例相关的名字。  指定了由容器载入的实现类。您能随意地包含一个   子元素为过滤器实例提供初始化参数。  标记代表了一个过滤器的映射,指定了过滤器会对其产生作用的 URL 的子集。

lightningboard 项目中的web.xml文件如下:



  
     controllerFilter
     lightningboard.ControllerFilter
  

  
     sessionAuthorizationFilter
     lightningboard.filter.SessionAuthorizationFilter
    
       ERROR_PAGE
       login.jsp
    
    
       OBJECT_NAME
       loginBean
    
  

  
     sessionAuthorizationFilter
     /post.do
  
  
     sessionAuthorizationFilter
     /postP.do
  
  
     sessionAuthorizationFilter
     /post.jsp
  
  
     sessionAuthorizationFilter
     /userEdit.do
  
  
     sessionAuthorizationFilter
     /userEditP.do
  
  
     sessionAuthorizationFilter
     /userEdit.jsp
  
  
     sessionAuthorizationFilter
     /userList.do
  
  
     controllerFilter
     *.do
  
  
     index.html
  


  由于本人水平有限,不当之处还请指正,谢谢!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值