servlet——filter

1 概述

Filter是Servlet规范的三大组件之一。顾名思义,就是过滤。可以在请求到达目标资源之前先对请求进行拦截过滤,即对请求进行一些处理;也可以在响应到达客户端之前先对响应进行拦截过滤,即对响应进行一些处理。采用的责任链设计模式

2 生命周期

    Filter的生命周期与Servlet的生命周期类似,其主要生命周期阶段有四个:Filter对象的创建、Filter对象的初始化、Filter执行doFilter()方法以及最终Filter对象被销毁。
    Filter的整个生命周期过程的执行,均由Web服务器负责管理。即Filter从创建到销毁的整个过程中方法的调用,都是由Web服务器负责调用执行的,程序员无法控制其执行流程。

3 Demo

1注册filter

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>fiter.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/</url-pattern>
  </filter-mapping>

2 实现Filter接口

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	// 做某些操作
        request.setCharacterEncoding("utf-8");
        // 责任链的引用
        chain.doFilter(request,response);
    }
    @Override
    public void destroy() {
    }
}

4 FilterChain

FilterChain接口类对象是被用于Tomcat等容器提供给开发者从视图到资源过滤请求的调用链的对象。过滤器使用过滤器链来调用链中的下一个过滤器,如果正在调用的过滤器是链中的最后一个,则会直接调用链末尾端的资源。

5 Filter详解

5.1 特点

  • Filter是单例多线程的。
  • Filter是在应用被加载时创建并初始化的,这是与Servlet不同的地方。Servlet是在该Servlet被第一次访问时创建的。Filter与Servlet的共同点是,其无参构造器与init()方法只会执行一次。
  • 用户每提交一次该Filter可以过滤的请求,服务器就会执行一次doFilter()方法,即doFilter()方法可以被多次执行。
  • 当应用被停止时执行destroy()方法,Filter被销毁,即destroy()方法只会执行一次。
  • 由于Filter是单例多线程的,所以为了保证其线程安全性,一般情况下是不为Filter类定义可修改的成员变量。因为每个线程均可修改这个成员变量,会出现线程安全问题。

5.2 dispatcher

  • 在中还有一个子标签,用于设置过滤器的请求类型。其有四种取值,REQUEST、FORWARD、INCLUDE、ERROR。
  • FORWARD:若请求是由一个Servlet通过RequestDsipatcher的forward()方法所转发的,那么这个请求将被值为FORWARD的Filter所拦截。即当前Filter只会拦截由RequestDispatcher的forward()方法所转发的请求。其他请求均不拦截。
  • INCLUDE:当前Fillter只会拦截由RequestDsipatcher的include()方法所转发的请求。其他请求均不拦截。
  • REQUEST:表示当前过滤其只会拦截普通请求,但是对forward和include的跳转不进行拦截。(默认值)
  • ERROR:表示当跳转到指定的错误处理页面时,这个跳转请求会被当前过滤器拦截。

5.3 Filter执行原理

  • 当某资源的请求到达Web容器时,会先对请求进行解析,使用解析出来的URI作为比较对象,从Map(Map的key为的值,value为Filter实例对象的引用)中查找是否存在相匹配的key。若存在,那么读取其value,即Filter对象的引用,将该引用存入到数组中。然后继续向后查找,直到将该Map查找完毕。这样在数组中就存在按照查找顺序排好序的Filter引用。
  • 数组初始化完毕后,开始按照数组元素顺序进行执行。所以数组中的Filter全部执行完毕之后,再跳转到请求的目标资源。(数组中存放着与请求相匹配的所有Filter)

5.4 说明

  • 若Filter为全路径匹配方式,那么url-pattern只能写为/*,而不能够写为/。(写为/,无论是静态资源,还是动态资源都不起作用)
  • 标签中可以不使用,但需要指定,即当前过滤器拦截的是对指定Servlet的请求。

6 应用

解决中文乱码问题,过滤敏感词、安全权限检查等

<filter>
   	<filter-name>CharacterEncodingFilter</filter-name>
   	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   	<init-param>
   		<param-name>encoding</param-name>
   		<param-value>UTF-8</param-value>
   	</init-param>
   	<init-param>
   		<param-name>forceEncoding</param-name>
   		<param-value>true</param-value>
   	</init-param>
</filter>
<filter-mapping>
   <filter-name>CharacterEncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

猜你喜欢

转载自blog.csdn.net/ccoran/article/details/84612532