目录
一、基本概念
一、基本概念
- 1、 Filter 过滤器它是 JavaWeb 的三大组件之一。 三大组件分别是: Servlet 程序、 Listener 监听器、 Filter 过滤器
- 2、 Filter 过滤器它是 JavaEE 的规范。 也就是接口
- 3、 Filter 过滤器它的作用是: 拦截请求, 过滤响应
过滤器的三要素:
①拦截
过滤器之所以能够对请求进行预处理,关键是对请求进行拦截,把请求拦截下来才能够做后续的操作。而且对于一个具体的过滤器,它必须明确它要拦截的请求,而不是所有请求都拦截。
②过滤
根据业务功能实际的需求,看看在把请求拦截到之后,需要做什么检查或什么操作,写对应的代码即可。
③放行
过滤器完成自己的任务或者是检测到当前请求符合过滤规则,那么可以将请求放行。所谓放行,就是让请求继续去访问它原本要访问的资源。
二、使用方法
- 要点1: 到 web.xml 中去配置 Filter 的拦截路径
- 要点2:实现javax.servlet.Filter接口
- 要点3:在doFilter()方法中执行过滤
- 要点4:如果满足过滤条件使用 chain.doFilter(request, response);放行
- 要点5:如果不满足过滤条件转发或重定向请求
典型案例:给admin设置权限,只能登录后访问
public class AdminFilter implements Filter {
/**doFilter 方法, 专门用于拦截请求。 可以做权限检查*/
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain{
//获取HttpServletRequest对象
HttpServletRequest httpReq= (HttpServletRequest) req;
//获取Session对象
HttpSession session = httpReq.getSession();
Object user = session.getAttribute("user");
// 如果等于 null, 说明还没有登录
if (user == null) {
req.getRequestDispatcher("/login.html").forward(req,resp);
return;
} else {
// 让程序继续往下访问用户的目标资源
filterChain.doFilter(req,resp);
}
}
}
<!--filter 标签用于配置一个 Filter 过滤器-->
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>com.test.filter.AdminFilter</filter-class>
</filter>
<!--filter-mapping 配置 Filter 过滤器的拦截路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern 配置拦截路径-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
三、生命周期
和Servlet生命周期类比,Filter生命周期的关键区别是:在Web应用启动时创建对象
四、过滤器匹配规则
4.1 精确匹配
指定被拦截资源的完整路径
<!-- 配置Filter要拦截的目标资源 -->
<filter-mapping>
<!-- 指定这个mapping对应的Filter名称 -->
<filter-name>TargetFilter</filter-name>
<!-- 通过请求地址模式来设置要拦截的资源 -->
<url-pattern>/TargetServlet</url-pattern>
</filter-mapping>
4.2 模糊匹配
使用模糊匹配可以让我们创建一个Filter就能够覆盖很多目标资源,不必专门为每一个目标资源都创建Filter,提高开发效率
4.2.1 /*
假如配置了url-pattern为/user/*之后,请求地址只要是/user开头的那么就会被匹配.
极端情况:/* :匹配所有请求
<filter-mapping>
<filter-name>Target02Filter</filter-name>
<!-- 模糊匹配:前杠后星 -->
<url-pattern>/user/*</url-pattern>
</filter-mapping>
4.2.2 *.xxx
我们使用png图片来测试后缀拦截的效果,并不是只能拦截png扩展名
<filter>
<filter-name>Target04Filter</filter-name>
<filter-class>com.filter.TargetFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TargetFilter</filter-name>
<url-pattern>*.png</url-pattern>
</filter-mapping>
注:不能使用 /*.png !!!!
五、过滤器链
- 多个Filter的拦截范围如果存在重合部分,那么这些Filter会形成Filter链。
- 浏览器请求重合部分对应的目标资源时,会依次经过Filter链中的每一个Filter。
- Filter链中每一个Filter执行的顺序是由web.xml中filter-mapping配置的顺序决定的。
举例:
<filter-mapping>
<filter-name>TargetChain03Filter</filter-name>
<url-pattern>/TargetServlet</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>TargetChain02Filter</filter-name>
<url-pattern>/TargetServlet</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>TargetChain01Filter</filter-name>
<url-pattern>/TargetServlet</url-pattern>
</filter-mapping>
控制台输出:
测试Filter链:TargetChain03Filter
测试Filter链:TargetChain02Filter
测试Filter链:TargetChain01Filter
六、FilterConfig 类
- FilterConfig 类见名知义, 它是 Filter 过滤器的配置文件类。
- Tomcat 每次创建 Filter 的时候, 也会同时创建一个 FilterConfig 类, 这里包含了 Filter 配置文件的配置信息。
- FilterConfig 类的作用是获取 filter 过滤器的配置内容
- 1、 获取 Filter 的名称 filter-name 的内容
- 2、 获取在 Filter 中配置的 init-param 初始化参数
- 3、 获取 ServletContext 对象
public void init(FilterConfig filterConfig) throws ServletException {
1、 获取 Filter 的名称 filter-name 的内容
System.out.println("filter-name 的值是: " + filterConfig.getFilterName());
2、 获取在 web.xml 中配置的 init-param 初始化参数
System.out.println("初始化参数 username 的值是:"+filterConfig.getInitParameter("username"));
3、 获取 ServletContext 对象
System.out.println(filterConfig.getServletContext());
}
<!--filter 标签用于配置一个 Filter 过滤器-->
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>com.filter.AdminFilter</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
</filter>