在web.xml文件中,我们经常可以看到配置的统一编码过滤器,他继承了OncePerRequestFilter,而OncePerRequestFilter继承自GenericFilterBean,GenericFilterBean实现了filter,因此可见CharacterEncodingFilter具有filter的所有特性;即实现拦截请求的功能,在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。 

<filter>
<filter-name>encoding-filter</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>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

url-pattern配置为/*表示拦截客户端浏览器所有的请求;其中在web容器启动的时候会调用CharacterEncodingFilter来实现将init-param中配置的参数记载进来;下面是tomcat启动过程中set值的过程(debug模式):

web.xml中配置CharacterEncodingFilter编码过滤器的原理_tomcat

可见配置的utf-8编码集已经加载进来。tomcat启动后,浏览器每次发出请求 ,都会经过我们配置的编码过滤器,最后调用doFilterInternal()方法执行过滤任务:

web.xml中配置CharacterEncodingFilter编码过滤器的原理_web服务器_02

另外:Filter生命周期

和Servlet一样Filter的创建和销毁也是由WEB服务器负责。不过与Servlet区别的是,它是在应用启动的时候就进行装载Filter类(与Servlet的load-on-startup配置效果相同)。容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)。当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。
注意:init方法与destroy方法只会直接一次。