Filter

Filter 的作用是拦截请求和响应的,拦截之后,是为了修改请求和响应中的内容。

   

生命周期 filter 的生命周期:

由web 服务器进行管理,也就是说,filter的整个过程中的方法调用,都是由web 服务器进行调用执行。程序员无法控制其执行。

Filter

   

//Filter 是在应用被启动时被创建以及初始化的。

//filter 是单例多线程的。

//filter 是在应用被停止的时候销毁的

//dofilter() 方法,无论是哪个线程进行访问,就会执行Filter doFilter() 方法。

//并且每过滤一次,就会执行一次dofilter() 方法

//由于filter 是单例多线程的,为了保证其线程安全性,一般是不为filter 添加可修改的成员变量的。

   

Filter 的注册流程:

(1)写一个类实现 filter 接口

(2)拷贝类全名,然后再web.xml 中注册

Eg:

<filter>

        <!--filter 的名称 -->

        <filter-name>some-Filter</filter-name>

        <filter-class>com.cau.filters.SomeFilter</filter-class><!-- filter 的实现类 -->

        <!--初始化参数 -->

        <init-param>

                <param-name>college</param-name>

                <param-value>csu</param-value>

        </init-param>

</filter>

<filter-mapping>

        <filter-name>some-Filter</filter-name>

        <url-pattern>/*</url-pattern><!--所有请求他通通过滤拦截 -->

</filter-mapping>

   

   

   

   

Filter 的工作原理:

可以在请求到达目标资源之前对请求先进行拦截过滤,及对请求进行处理。也可以在响应到达客户端之前对响应进行处理,即对响应进行过滤和拦截。

Filter

   

Filter 一般是有三个方法:

(1) public void init(FilterConfig filterConfig)

filterConfig 指的是filter 在web.xml中的注册信息,filterConfig 和ServletConfig 类似,是一个接口。

有以下几种方法,以及方法的使用如下:

// 获取filter name

String name = filterConfig.getFilterName();

System.out.println("filterName" + name);

   

// 获取所有的初始化参数的名称

Enumeration<String> names = filterConfig.getInitParameterNames();

// 遍历枚举

while (names.hasMoreElements()) {

String name1 = names.nextElement();

String value = filterConfig.getInitParameter(name1);

System.out.println("filterName" + name1 + "==" + "value" + value);

   

}

//获取全局域

ServletContext servletContext = filterConfig.getServletContext();

System.out.println("ServletContext="+servletContext);

   

//将请求放到下一资源

chain.doFilter(request, response);

   

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

(3)public void destroy()

   

   

详解 filter 中的<Filter-mapping />

<!--

        filter 为全路径匹配方式(也就是说所有的请求都可以拦截)url-pattern 只能写成 /*,而不能写为 /

        /* 表示servlet 可以匹配所有的请求,无论是静态资源还是动态资源

        / 不会拦截动态资源请求,只会拦截静态

-->

   

<!-- filter-mapping 中可以不使用 url-pattern ,但是需要指定servlet-name,即当前过滤器,只针对指定的servlet请求, -->

   

<Filter-mapping/> 中的dispatcher

(1)FORWARD

当前过滤器只会拦截RequestDispatcher的 forward()方法,所转发的请求。其余请求均不拦截

Filter

(2)INCLUDE

   

Filter

   

(3)REQUEST

当前过滤器会拦截普通请求。,但是对于forward 和include的跳转不进行拦截,是默认值

(4)ERROR

表示当跳转到指定的 错误处理页面时,这个跳转请求,会被当前过滤器拦截。

   

   

Filte执行的顺序

当存在多个Filter 的时候,其执行顺序。与注册顺序一致。

   

Filter

   

   

Filter的执行原理,以及与servlet 执行原理的比较:

/**

* 回顾servlet的执行原理

* 两个map:

* web 容器中存在两个map,这连个mapkey 均为注册时的 utl-pattern 的值。但是其value 是不同的

* 第一个mapvalueservlet 实例对象的引用

* 第二个mapdevalue <servlet-class/> 的值,即servlet 的全限定名

*

* 执行原理:

* servlet的请求到达servlet容器时,会先对请求进行解析,使用解析出的uti,作为比较对象。

* 从第一个map中察找是否有相同的key

* 若存在相同的key,读取value ,servlet 对象的引用,执行servlet() service() 方法

* 若不存在相同的key,那么再从第二个map中查找是否存在相同的key,若存在则读取其value,即要访问的servlet的全限定类名。

* 然后使用反射机制创建servlet 实例,并将实例写入第一个map中,然后再执行该servletservice() 方法。

* 若第二个map中也没有找到,就是 404 not found

*/

   

/**

*filter的执行原理:

*一个数组,一个map        

*map key<url-pattern/> 的值,value filter 实例对象的引用。

*数组: 存放着        与请求相匹配的所有filter

*

*执行原理:

*当对某资源的web请求到达web容器时,会先对请求进行解析,使用解析出的uri作为比较对象,在map中查找是否存在相匹配的key

*若存在,读取其value,即filter对象的引用,将该引用存入到数组中。然后继续向后查找,直到将该map查找完毕,这样数组中就会有

*按照查找顺序排好序的filter 引用

*数组初始化完毕之后 ,开始按照数组元素顺序进行执行,所有数组中德 filter全部执行完毕之后,在跳到所请求的资源

*

*/

   

/**

* servlet filter的不同的原因是 两者的实例创建时机是不一样的。

* servlet 是在请求的时候

* filter 是在项目启动的时候,就创建了。

*/