过滤器链调用原理与顺序:
web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法(放行)中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。根据在web.xml文件中的顺序还决定调用的顺序:和<filter-mapping>的配置先后顺序有关系.
在开发中:Servlet,Filter,Listener配置先后问题: 一般先配置Listener,再配置Filter,最后配置Servlet.
过滤器链代码测试:chain.doFilter(req, resp);//放行
public class AFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("开始Afilter");
chain.doFilter(request, response);
System.out.println("结束AFilter");
}
@Override
public void destroy() {
}
}
public class BFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("开始Bfilter");
chain.doFilter(request, response);
System.out.println("结束BFilter");
}
@Override
public void destroy() {
}
}
CFilter:
public class CFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("开始Cfilter");
chain.doFilter(request, response);
System.out.println("结束CFilter");
}
@Override
public void destroy() {
}
}
配置web.xml文件:<filter>
<filter-name>a</filter-name>
<filter-class>cn.itsource._01_filterchain.AFilter</filter-class>
</filter>
<filter>
<filter-name>b</filter-name>
<filter-class>cn.itsource._01_filterchain.BFilter</filter-class>
</filter>
<filter>
<filter-name>c</filter-name>
<filter-class>cn.itsource._01_filterchain.CFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>a</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>b</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>c</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
请求的顺序:开始Afilter——开始Bfilter——开始Cfilter 响应的顺序:结束CFilter——结束BFilter——结束AFilter
上面三个过滤器的执行流程:开始Afilter——开始Bfilter——开始Cfilter——结束CFilter——结束BFilter——结束AFilter
配置路径的细节:
a.精确拦截指定资源
<url-pattern>/hello</url-pattern>:当前Filter只对/hello这个资源做过滤.
b.拦截所有资源
<url-pattern>/*</url-pattern>:当前Filter对所有的请求做过滤.如字符编码
c.对部分资源进行拦截(以什么开头)
<url-pattern>/system/*</url-pattern>:当前Filter 对/system/之后的请求做过滤.
比如:/system/list,/system/edit,/system/delete 如权限判断
d.对部分资源进行拦截(以什么结束)
<url-pattern>*.html</url-pattern>:当前Filter 对后缀是ejf的进行过滤。如假静态化
过滤器过滤类型选择:
过滤器默认过滤的类型是:request。要想过滤其它的需要在web.xml中配置
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
Filter默认情况下,就只能对一次请求做过滤.
<dispatcher>REQUEST</dispatcher>
若需要对请求转发做过滤:
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>