Filter
1.什么是Filter过滤器
1、Filter 过滤器它是JavaWeb 的三大组件之一。三大组件分别是: Servlet 程序、Listener 监听器、Filter 过滤器
2、Filter 过滤器它是JavaEE 的规范。也就是接口
3、Filter 过滤器它的作用是: 拦截请求,过滤响应
拦截请求常见的应用场景有:
1、权限检查
2、日记操作
3、事务管理
2.Filter使用
要求: 在你的 web 工程下,有一个admin 目录。这个admin目录下的所有资源 (html 页面、jpg 图片、jsp 文件等等) 都必须是用户登录之后才允许访问。
思考: 根据之前我们学过内容。我们知道,用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否登录,可以判断 Session 中否包含有用户登录的信息即可!
public class AdminFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
//此方法实现拦截请求和过滤响应操作
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
if(user == null){
//转发到首页
httpServletRequest.getRequestDispatcher("/index.jsp").forward(servletRequest,servletResponse);
return;
}else {
//让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
在web.xml中配置Filter
<!--filter标签用于配置一个filter过滤器-->
<filter>
<!--给filter起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置filter的全类名-->
<filter-class>com.filter.demo.AdminFilter</filter-class>
</filter>
<!--filter-mapping配置Filter过滤器的拦截路径-->
<filter-mapping>
<!--filter-name表示当前的拦截路径给哪个filter使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到IDEA的web目录
/admin/* 表示请求地址为:http://ip:port/工程路径/admin/*
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
验证访问,可以看到转发到了首页,请求得到了拦截
3.Filter的生命周期
Filter 的生命周期包含几个方法
1、构造器方法
2、init初始化方法
第1,2步,在 web 工程启动的时候执行 (Filter 已经创建)
3、doFilter 过滤方法
第3 步,每次拦截到请求,就会执行
4、destroy 销毁
第4步,停止 web 工程的时候,就会执行(停止 web 程,也会销毁 Filter 过滤器)
4.FilterConfig类
FilterConfig 类见名知义,它是 Filter 过滤器的配置文件类
Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息
FilterConfig 类的作用是获取 filter 过滤器的配置内容
1、获取 Filter 的名称 filter-name 的内容
2、获取在 Filter 中配置的 init-param 初始化参数
3、获取 ServletContext 对象
5.FilterChain过滤器链
5.1 FilterChain
FilterChain,就是过滤器链(多个过滤器如何一起工作),FilterChain里只有一个doFilter方法
FilterChain.doFilter() 方法的作用
1、执行下一个Filter过滤器 (如果有Filter)
2、执行目标资源 (没有Filter)
这里看来,Filter不仅可以对请求前进行处理,也可以对响应后进行处理,体现了面向切面编程AOP的思想
5.2 执行顺序
在多个Filter过滤器执行的时候,它们执行的优先顺序是由他们在web.xml中从上到下配置的顺序决定! ! !
这里配置两个Filter,验证执行顺序
public class Filter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter1 前置代码");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Filter1 后置代码");
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
public class Filter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter2 前置代码");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Filter2 后置代码");
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
<filter>
<filter-name>Filter1</filter-name>
<filter-class>com.filter.demo.Filter1</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/target.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>Filter2</filter-name>
<filter-class>com.filter.demo.Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/target.jsp</url-pattern>
</filter-mapping>
结果:
5.3 执行特点
1、所有filter和目标资源默认都执行在同一个线程中
2、多个Filter共同执行的时候,它们都使用同一个Request对象。
5.4 拦截路径匹配规则
-
精确匹配
<url-pattern>/target.jsp</url-pattern>
以上配置的路径,表示请求地址必须为: http://ip:port/工程路径/target.jsp
-
目录匹配
<url-pattern>/admin/*</url-pattern>
以上配置的路径,表示请求地址必须为: http://ip:port/工程路径/admin/*
-
后缀名匹配 (不能以 / 开头,否则报错)
<url-pattern>*.html</url-pattern>
以上配置的路径,表示请求地址必须以.html 结尾才会拦截到
<url-pattern>*.do</url-pattern>
以上配置的路径,表示请求地址必须以.do 结尾才会拦截到
<url-pattern>*.action</url-pattern>
以上配置的路径,表示请求地址必须以.action 结尾才会拦截到
Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!