Filter过滤器
Filter过滤器介绍
- 什么是Filter过滤器
Filter是JavaWeb三大组件之一,是JavaEE的规范也即接口。作用主要是拦截请求、过滤响应。在本文主要介绍其拦截请求的使用。 - Filter的工作流程
客户端向服务器发送请求之后,如果存在该请求路径对应的过滤器,则会先执行过滤器中声明的逻辑,如果通过该逻辑,则请求可以访问目标路径,否则请求会被过滤器拦截执行其他过滤器指定的操作 - Filter使用步骤
- 编写一个类实现Filter接口
- 实现过滤方法doFilter()
- 在web.xml中配置Filter的拦截路径
public class FilterTest extends Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
Object user = httpServletRequest.getSession().getAttribute("user");
if (user == null) {
httpServletRequest.getRequestDispatcher("/pages/user/login.jsp").forward(servletRequest,servletRes ponse);
} else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() { }
}
-
Filter的声明周期
- 构造器方法:在web工程启动时就会被执行
- init初始化方法:在web工程启动时就会被执行
- doFilter方法:当每次拦截到请求时就会执行
- destroy方法:在web工程停止时会执行,并销毁Filter过滤器
-
FilterConfig类
FilteConfig类时Filter过滤器的配置文件类,在Tomcat每次创建Filter时,就会同时同时创建一个FilterConfig类,这里包含了Filter配置文件的配置信息
FilterConfig的作用是获取Filter的配置信息:- 获取Filter的名称
<filter-name>
- 获取Filter中配置的
<init-param>
初始化参数 - 获取ServletContext对象
- 获取Filter的名称
-
FilterChain过滤器链
用于协调配置多个过滤器如何一起工作,当有多个Filter过滤器时,在doFilter方法中会执行chain.doFilter()来执行下一个过滤器或者访问目标资源。
- 多个Filter执行的特点
- 所有的Filter过滤器和目标资源默认都执行在同一个线程中
- 多个Filter过滤器在共同执行时,会使用同一个Request对象
- FilterChain.doFilter方法执行后,会自动执行下一个Filter过滤器,或者目标资源。这里需要明确以下几点
- 多个Filter执行的过程中,他们的优先顺序是根据他们在web.xml文件中的配置上下顺序决定的
- 这里的多个Filter过滤器指,在web.xml文件中配置的过滤地址相同的过滤器,在这些过滤器一一执行完毕后,继续访问目标资源。若目标资源路径还有其他的过滤器,继续执行这些过滤器。
- 多个Filter执行的特点
-
Filter的拦截路径
- 精确匹配 :即web.xml文件中的拦截路径为精确地目标资源,如
<url-pattern>/target.jsp</url-pattern>
- 目录匹配:即拦截路径为一个目录,表示拦截该目录下的所有资源文件,如
<url-pattern>/abc/*</url-pattern>
- 后缀名匹配:即拦截路径是针对于某一类后缀名的,只要请求地址后缀名匹配,该请求就会被拦截,如
<url-pattern>*.jsp</url-pattern>
注意,Filter过滤器只关心请求的地址是否匹配拦截地址,并不在乎请求的该资源地址是否存在。也就是说即使目标资源不存在,但是只要符合拦截条件,Filter过滤器都会将该请求拦截下来执行相关操作。
- 精确匹配 :即web.xml文件中的拦截路径为精确地目标资源,如
使用Filter和ThreadLocal来组合管理事务
ThreadLocal
ThreadLocal可以用于解决多线程的数据安全问题。ThreadLocal可以给当前线程关联一个数据,这个数据可以是普通变量,也可以是对象、数组、集合等等。(其实相当于是以当前线程为KEY,关联数据为VALUE的键值关系)但是需要注意的是,一个ThreadLocal对象实例只能够给当前线程关联一个数据,当需要给线程关联多个数据时,需要使用多个ThreadLocal的实例来满足条件。每个ThreadLocal对象在定义实例的时候,一般都是static类型,而且当线程销毁的时候,ThreadLocal中保存的数据会被JVM自动释放。
- ThreadLocal使用起来非常简单,只需要调用threadLocal对象实例的set()方法就可以将想要的数据与线程关联,而使用threadLocal对象的get()方法就可以返回获得与线程关联的数据。
在工程中使用ThreadLocal的意义在于,为了使是所有的DAO操作都在一个数据库连接Connection中完成,这样能够避免DAO中因出现异常导致的事务问题。(主要是为了将一个逻辑的所有数据库操作合并成为事务,让这些操作以事务的形式在一次连接中同时完成,这样如果出现异常,也可以通过回滚来将整个事务的所有数据库操作同时回滚,避免了部分操作异常导致的数据库泄露)。
使用Filter和ThreadLocal结合使用,可以使逻辑所需的所有DAO层操作都使用ThreadLocal来实现。