笔记——过滤器与包装器

与servlet类似,过滤器就是Java组件,请求发送到servlet之前,可以用过滤器截获和处理请求,另外servlet结束工作之后,但在响应发回给客户之前,可以用过滤器处理响应。

<?xml version="1.0"encoding="UTF-8"?>

<web-app version="2.5"

         xmlns="http://java.sun.com/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

 <display-name></display-name>        

 <welcome-file-list>

   <welcome-file>index.jsp</welcome-file>

 </welcome-file-list>

 

 <filter>

       <filter-name>BeerRequest</filter-name>

       <filter-class>com.BeerRequestFilter</filter-class>     

       <init-param>             <!-- 可选,可以有多个 -->

                <param-name>LogFileName</param-name>

                <param-value>UserLog.txt</param-value>

       </init-param>

 </filter>

 

 <filter-mapping>

       <filter-name>BeerRequest</filter-name>

       <url-pattern>*.do</url-pattern>              <!-- 开头没有/-->        

       <!--

                url-pattern 对应URL模式的过滤器映射,定义哪些Web应用资源使用这个过滤器

                servlet-name   对应Servlet名的过滤器映射

                如:<servlet-name>AdviceServlet</servlet-name>

        -->

        <!-- 2.4版本

               <dispatcher>REQUEST</dispatcher>为通过请求分派请求的Web资源声明一个过滤器映射

               REQUEST(默认) INCLUDE FORWARDERROR      (可包含0~4个)

         -->

 </filter-mapping>

</web-app>

建立请求跟踪过滤器

package com;

import java.io.IOException;

import javax.servlet.*;

import javax.servlet.http.*;

public class RequestFilter implementsFilter {

         privateFilterConfig fc;

        

         publicvoid init(FilterConfig config) throws ServletException {

                   this.fc= config;

         }

        

         //参数不取HTTP请求和响应对象做参数,而只是常规的ServletRequest和ServletResponse对象

         publicvoid doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)

                                                                 throwsServletException, IOException {

                   HttpServletRequesthttpReq = (HttpServletRequest) req;

                   Stringname = httpReq.getRemoteUser();

                   if(name!= null) {

                            fc.getServletContext().log("User" + name + "is updating");

                   }

                   chain.doFilter(req,resp);         //链接到下一个组件(Servlet或过滤器)

         }

        

         publicvoid destroy() {

                  

         }

}

**如果要用响应过滤器对响应做出处理再发回给客户**

在正常情况下tomcat容器connector处理一次客户端http请求时的处理流程是:创建HttpServletRequest请求、HttpServletResponse响应和ClientJSPorServlet客户JSP或Servlet对象实例,然后调用service方法完成处理。加入过滤器Filter和封装类Wrapper后情况有所改变,使调用过程发生了变化。容器在初始化时先创建Filter对象示例,当用客户端请求时将先转给Filter进行处理(根据过滤器的url-pattern设置拦截那些请求),由Filter过滤器决定滞后的处理流程(或正常处理或中断、转向等有代码控制);Filter将HttpServletRequest请求和封装后的HttpServletResponseWrapper响应转给客户JSP或Servlet对象进行处理,处理结束后又回到过滤器,我们在这里加入信息过滤处理过程,然后再将数据写回HttpServletResponse对象,响应客户端。由此可见,HttpServletResponseWrapper是一个封装后的“假”响应对象,我们真是使用假的响应对象获取了响应数据,只是在写回数据调用输出流时发生了问题:在JSP或Servket(Java Servlet)中调用了getWriter()或getOutputStream()方法时,如果在Wrapper中实现了(覆盖)这两个方法,则调用Wrapper中的方法;如果没有实现,则相当于调用HttpServletResponse中方法;而我们在写回数据时必须调用getWriter()或getOutputStream()方法。

如:

public void doFilter(ServletRequest req,ServletResponse resp, FilterChain chain)

                                                                 throwsServletException, IOException {

                   //定制包装器类包装响应

                   MyResponseWrappermrw = new MyResponseWrapper((HttpServletResponse)resp);

                   //发送定制的响应对象

                   chain.doFilter(req,mrw);        

                   /*

                    * 这里完成响应处理

                    */

         }

包装器

如果你想创建定制请求或响应对象,只需要派生某个便利请求或响应“包装器”类。包装器包装了实际的请求或响应对象,而且吧调用委托传给实际的对象,还允许你对定制请求或响应做所需的额外处理。

*ServletRequestWrapper

*HttpServletRequestWrapper

*ServletResponseWrapper

*HttpServletResponseWrapper

猜你喜欢

转载自blog.csdn.net/qq_34902684/article/details/71642623
今日推荐