什么是过滤器
Filter介于客户端与Servlet之间,它既可以拦截客户端对Servlet的请求,也可以改变Servlet对客户端的响应。
使用过滤器
使用过滤器有两件事情要做:
- 实现Filter接口
- 配置Filter,也就是把Filter注册到ServletContext的运行上下文。
@WebFilter(filterName = "TestFilter",urlPatterns = "/*",
initParams = {
@WebInitParam(name="initParamName",value="this is a test filter")
})
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化过滤器
String filterName = filterConfig.getFilterName();//获取过滤器名
String initParamName = filterConfig.getInitParameter("initParamName");//获取初始化参数
ServletContext servletContext = filterConfig.getServletContext();//返回应用上下问
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("前置处理");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("后置处理");
}
@Override
public void destroy() {
//销毁过滤器时执行
}
}
上面使用注解配置Filter,也可以使用web.xml来配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>com.patermenkey.helloweb.filter.TestFilter</filter-class>
<init-param>
<param-name>initParamName</param-name>
<param-value>this is a TestFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注意
- 传入的参数时ServletRequest和ServletResponse,如果需要使用HttpServletrequest和HttpServletResponse需要自己进行向下转型。
- Filter是随着应用被创建和销毁的,因此init()和destory()是在初始化环境和销毁环境时调用的,而不是每次请求时
Filter执行顺序
与Servlet不同,Servlet按匹配的优先级只选择一个匹配的Servlet。Filter则是会将所有匹配的Filter建立一个执行链,其顺序由XML中出现的先后顺序决定。也就是说注解配置就没有办法决定执行顺序了。
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SecondFilter</filter-name>
<filter-class>filter.SecondFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecondFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter>
<filter-name>ThirdFilter</filter-name>
<filter-class>filter.ThirdFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ThirdFilter</filter-name>
<url-pattern>/test.do</url-pattern>
</filter-mapping>
像上面这样配置Filter的话,当输入/test.do时,Filter会按First,Second,Third的顺序执行,而与匹配的URL无关。
拦截的请求方式
Filter可以设置dispatcherTypes属性设置过滤的请求方式。它有以下几个属性
- DispatcherType.FORWARD
- DispatcherType.REQUEST
- DispatcherType.INCLUDE
- DispatcherType.ERROR
- DispatcherType.ASYNC
默认只有DispatcherType.REQUEST,即只有通过URL访问的请求再回被过滤。如果希望RequestDispatcher.foward(),RequestDispatcher.include()和ajax异步请求也被过滤的话则要加上对应的属性。