过滤器要点:

filter是在servlet/JSP执行前后都会执行,chain.doFilter(request,   response)之前的代码在servlet/JSP之前执行,chain.doFilter(request,  response)之后的代码在servlet/JSP之后执行。  

  3、整个流程是客户端发出请求后,先执行filter里面dofilter方法的chain.doFilter之前的代码,然后通过chain.doFilter调下一个filter,如果没有下一个,则调用客户端请求的servlet/JSP。然后倒着执行每个filter里面chain.doFilter(request, response)之后的代码。

Servlet Filtering

过滤器(filter)是Java类,可以改变请求(request)和响应(response)的头信息与内容信息。过滤器不同于其他Web组件的地方是它本身并不创建响应(response),然而它可以依附在任何类型的Web资源上。过滤器截取请求(request),检查和改变request对象、response对象,并可以执行一些其他的任务。过滤器提供的主要功能是:

·        实现日志功能

·        实现用户定义的安全功能

·        调试功能

·        权限过滤

·        改变发送给客户端的响应(response)

·        

·        服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法。执行的顺序就如上图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。
过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前,这样才能确保在使用请求中的数据前设置正确的编码。

过滤器截获对特定命名的一个资源和一组资源的请求(request),然后执行过滤器中的代码。对于特定的资源,可以指定按照一定顺序调用的一个和多个过滤器,这就组成了链(chain)。使用过滤器主要包括:

·        编写过滤器类

·        为特定的Web资源指定过滤器链

1.1. 编写过滤器类

编写过滤器的API是javax.servlet包中Filter、FilterChain和FilterConfig接口中定义的一些方法。定义一个过滤器就是实现Filter接口。Filter接口中最主要的方法是doFilter()方法,它接收三个参数:request对象、response对象、filterchain对象。


void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)


这个方法能够执行的动作包括:

·        检查请求(request)的头信息

·        定制request对象,改变请求(request)的头信息或数据

·        定制response对象,改变响应(response)的头信息或数据

·        调用在过滤器链中的下一个实体。如果当前过滤器是链中的最后一个过滤器,那么下一个实体就是客户请求(request)的资源;否则,链中的下一个过滤器会被调用。通过chain对象的doFilter()方法调用下一个实体,并传递request对象和response对象作为参数。另外,也可以不调用doFilter()方法阻塞请求(request),这样,过滤器应该负责填充对客户的响应(response)。

·        检查响应的头信息

·        抛出异常显示处理过程中的错误

除了doFilter()方法,开发人员也必须实现init()和destroy()方法。当容器创建过滤器实例时调用init()方法,


void init(FilterConfig filterConfig)


可以从FilterConfig对象中获得初始化参数。

在部署描述文件中加入<filter>标记 ,此标记包括:

<filter-name>:过滤器名称
<filter-class>:过滤器的实现类
<init-params>:过滤器的初始参数
<filter>
  <filter-name>Compression Filter</filter-name>
  <filter-class>CompressionFilter</filter-class>
  <init-param>
     <param-name>compressionThreshold</param-name>
     <param-value>10</param-value>
  </init-param>
</filter>

登录过滤

 

@Override
    publicvoid doFilter(ServletRequest request, ServletResponse response,
           FilterChain chain) throws IOException, ServletException {
       // TODO Auto-generated method stub
       System.out.println("LoginServlet.doFilter()---> in");
       HttpServletRequest request1 = (HttpServletRequest) request;
       System.out.println(request1.getRequestURI());
       System.out.println(request1.getRequestURL());
       String ruri = request1.getRequestURI();
       if (ruri!=null&&((ruri.indexOf("login.jsp")!=-1||ruri.indexOf("image.jsp")!=-1)||ruri.indexOf("loginServlet.do")!=-1)) {
           chain.doFilter(request1, response);
       }else{
           HttpSession  session
           User user = (User)  session.getAttribute("user");
           if(user==null){
              String path =  ((HttpServletRequest) request).getContextPath();
              String basePath =  ((HttpServletRequest) request).getScheme()+"://"+ ((HttpServletRequest) request).getServerName()+":"+ ((HttpServletRequest) request).getServerPort()+path+"/";
              ((HttpServletResponse)response).sendRedirect(basePath+"login.jsp");
           }else{
              chain.doFilter(request1, response);
              System.out.println("LoginServlet.doFilter()---> out ");
           }
       }