过滤器
1.什么是过滤器
相当于访问公司之前必须到前台进行填表登记,才可以进入,之后在离开该公司时候,也需要签署何时签退的表格
2.Filter主要使用场合
整站字符集编码配置;
会员登录检测;
会员权限检测;
3.Filter原理——在访问最终资源前进行过滤判断
可以级联判断,形成过滤器链:
4Filter中的过滤判断
1)过滤器类要实现javax.servlet.Filter接口
2)过滤器类要重写或实现doFilter()
3)Filter中的过滤判断:
如果允许调用下一个资源,则调用过滤器链对象的doFilter()方法;
如果没有使用doFilter方法,则请求阻止。
javax.servlet.FilterConfig的doFilter方法和filter的doFilter方法不一样
如果不允许调用下一个资源,则return即可;
一般在return之前,重定向到某个资源。
5.Filter过滤器涉及的三个主要的接口
javax.servlet.Filter;
javax.servlet.FilterChain;
javax.servlet.FilterConfig;
javax.servlet.Filter过滤器主要接口,实现过滤功能,要配置url,以便只针对特定url下的资源进行过滤;
javax.servlet.FilterChain过滤器链接口,主要用于跳转下一个资源,实现链式逻辑;
javax.servlet.FilterConfig过滤器配置接口,主要用于在init()方法中读取配置数据。
6.在web.xml中配置filter
7.实例
创建web项目
在根目录文件下创建jsp文件,这里以index.jsp为例:
在 java Resources中编写过滤器的类,必须实现javax.servlet.Filter接口
FilterLifeFilter.java相关代码
package hxt.edu.Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* Servlet Filter implementation class FilterLifeFilter
*/
@WebFilter("/FilterLifeFilter")
public class FilterLifeFilter implements Filter {
/**
* Default constructor.
*/
public FilterLifeFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
print("init");
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
print("doFilter");
//chain.doFilter(request, response);
//print("chain doFilter end 过滤结束");
}
/**
* @see Filter#destroy()
*/
public void destroy() {
print("destroy");
}
void print(String info) {
// 打印线程的名称
System.out.println(info + " thread name: " + Thread.currentThread().getName());
}
}
之后配置web.xml文件
运行项目,启动Tomcat服务器,如果我们注释掉了doFilter()方法中的chain.doFilter(request, response);
则我们启动服务器的时候,网页不会显示内容,
如果没有注释掉chain.doFilter(request, response);
则会走下一个配置了url-pattern的过滤器,如果最终的过滤器走完,则访问最终数据,返回给客户端
在这里,我自己编写了模拟过滤链的代码
创建三个过滤器类
在每个过滤器的void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
方法中编写代码
在FirstFilter中
在SecondFilter中
在ThirdFilter中
可以在web.xml中配置,或者直接在头部的@WebFilter("/Bill/FilterTest.jsp")
中配置
在对应的过滤器中配置相同的url-pattern,例如这里我需要对我的webContent下的Bill下的FilterTest.jsp进行过滤
所以,在这三个合在一起的过滤链中的每个url-pattern中的配置都是/Bill/FilterTest.jsp,如果需要对Bill下所有的文件都进行过滤,则/Bill/*,其中星号代表全部,或者以某个字符打头的/L后边跟上星号。
最后运行服务器之后,在控制台中可以看到,我们最开始编写的一个过滤器生命周期类,来观看过滤器的生命周期,先调用init()方法之后执行doFilter()方法,之后执行doFilter()中调用的 FilterChain实例对象,调用FilterChain对象的doFilter()方法,执行下一个过滤,或者直接访问最终资源,init()的线程跟dofilter()方法的线程不一样
当我在此刷新一次页面,客户端又发送一次请求,过滤器又执行一次,但是不需要再次执行init()初始化操作,只是调用另外一个线程,doFilter()方法会在多个线程中被调用
当关闭服务器等的时候,过滤器才会执行destroy()方法
还有一种情况,当我们修改FilterLifeFilter.java的时候,会先销毁掉过滤器之后,再初始化一次