Servlet 中的 Filter

/ JavaWeb / 205浏览

Filter 也是在 web.xml 中一个常用的配置项,可以通过 组合来使用Filter。实际上Filter可以完成与Servlet同样的工作,甚至比Servlet使用起来更加灵活,因为它除了提供了request和response对象外,还提供了一个FilterChain对象,这个对象可以让我们更加灵活地控制请求的流转。

在Tomcat容器中,FilterConfig和FilterChain的实现类分别时ApplicatonFilterConfig和ApplicationFilterChain,而Filter的实现类由用户自定义,只要实现了Filter接口中定义的三个接口方法就行,这个三个方法和Servlet中的方法类似。只不过还有一个ApplicationFilterChain类,这个类可以将多个Filter串联起来,组成一个链。下面对Filter接口中的三个方法进行说明:

方法说明
initinit(FilterConfig var1)
初始化接口方法,在用户自定义的Filter初始化时被调用,它与Servlet的init()方法的作用是一样
的,FilterConfig与ServletConfig也类似,除了都能获取到容器的环境类 ServletContext 对象
之外,还能获取在 下配置的 参数值。
doFilterdoFilter(ServletRequest var1,ServletResponse var2, FilterChain var3)
在每个用户的请求时进来这个方法都会被调用,并在Servlet的service()方法之前被调用。
而FilterChain就代表当前这个请求链,所以通过调用FilterChain.doFilter可以将请求继续传递
下去。如果想拦截这个请求,可以不调用FilterChain.doFilter,那么这个请求就直接返回了。
所以Filter是一种责任链设计模式。
destroydestroy()
对象被销毁时,这个方法被调用。注意,当Web容器调用这个方法之后,容器会再调用一次
doFilter() 方法。

Filter类的核心还是传递的FilterChain对象,这个对象保存了到最终Servlet对象的所有Filter对象,这些对象都保存在ApplicationFilterChain对象的filters数组中。在FilterChain链上每执行一个Filter对象,数组的当前计数都会 +1,直到计数等于数组的长度,当FilterChain上所有的Filter对象执行完成后,就会执行最终的Servlet。所有在ApplicationFilterChain对象中会持有Servlet对象的引用。下图是Filter对象的执行时序图: alt

Filter存在的意义是提供一种拦截工作,可以将我们的Servlet对象执行之前或者执行之后处理一些特定的事情,来实现相应的业务逻辑。