过滤器之所以能够对请求进行预处理,关键是对请求进行拦截,把请求拦截下来才能够做后续的操作。而且对于一个具体的过滤器,它必须明确它要拦截的请求,而不是所有请求都拦截。
根据业务功能实际的需求,看看在把请求拦截到之后,需要做什么检查或什么操作,写对应的代码即可。
过滤器完成自己的任务或者是检测到当前请求符合过滤规则,那么可以将请求放行。所谓放行,就是让请求继续去访问它原本要访问的资源。
提示:将来学习SpringMVC时,会学习SpringMVC中的『拦截器』,同样具备三要素。
可看上一篇的Thymeleaf的基本用法。
public class Target01Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 1.打印一句话表明Filter执行了
System.out.println("过滤器执行:Target01Filter");
// 2.检查是否满足过滤条件
// 设定一个过滤条件:请求参数message是否等于monster
// 等于:放行
// 不等于:将请求跳转到另外一个页面
// ①获取请求参数
String message = request.getParameter("message");
// ②检查请求参数是否等于monster
if ("monster".equals(message)) {
// ③执行放行
// FilterChain对象代表过滤器链
// chain.doFilter(request, response)方法效果:将请求放行到下一个Filter,
// 如果当前Filter已经是最后一个Filter了,那么就将请求放行到原本要访问的目标资源
chain.doFilter(request, response);
}else{
// ④跳转页面
request.getRequestDispatcher("/SpecialServlet?method=toSpecialPage").forward(request, response);
}
}
@Override
public void destroy() {
}
}
这一步也可以叫『注册』。
<filter>
<filter-name>Target01Filterfilter-name>
<filter-class>com.cdz.filter.Target01Filterfilter-class>
filter>
<filter-mapping>
<filter-name>Target01Filterfilter-name>
<url-pattern>/Target01Servleturl-pattern>
filter-mapping>
和Servlet生命周期类比,Filter生命周期的关键区别是:在Web应用启动时创建对象
生命周期阶段 | 执行时机 | 执行次数 |
---|---|---|
创建对象 | Web应用启动时 | 一次 |
初始化 | 创建对象后 | 一次 |
拦截请求 | 接收到匹配的请求 | 多次 |
销毁 | Web应用卸载前 | 一次 |
指定被拦截资源的完整路径:
<filter-mapping>
<filter-name>Target01Filterfilter-name>
<url-pattern>/Target01Servleturl-pattern>
filter-mapping>
相比较精确匹配,使用模糊匹配可以让我们创建一个Filter就能够覆盖很多目标资源,不必专门为每一个目标资源都创建Filter,提高开发效率。
在我们配置了url-pattern为/user/*之后,请求地址只要是/user开头的那么就会被匹配。
<filter-mapping>
<filter-name>Target02Filterfilter-name>
<url-pattern>/user/*url-pattern>
filter-mapping>
极端情况:/*匹配所有请求
下面我们使用png图片来测试后缀拦截的效果,并不是只能拦截png扩展名。
<img th:src="@{/./images/img017.png}"/><br/>
<img th:src="@{/./images/img018.png}"/><br/>
<img th:src="@{/./images/img019.png}"/><br/>
<img th:src="@{/./images/img020.png}"/><br/>
<img th:src="@{/./images/img024.png}"/><br/>
<img th:src="@{/./images/img025.png}"/><br/>
<filter>
<filter-name>Target04Filterfilter-name>
<filter-class>com.atguigu.filter.filter.Target04Filterfilter-class>
filter>
<filter-mapping>
<filter-name>Target04Filterfilter-name>
<url-pattern>*.pngurl-pattern>
filter-mapping>
配置方式如下:
<url-pattern>/*.pngurl-pattern>
按照这个配置启动Web应用时会抛出异常:
java.lang.IllegalArgumentException: Invalid /*.png in filter mapping
结论:这么配是不允许的!
<filter-mapping>
<filter-name>Target05Filterfilter-name>
<servlet-name>Target01Servletservlet-name>
filter-mapping>
创建超链接访问一个普通的Servlet即可。
<filter-mapping>
<filter-name>TargetChain03Filterfilter-name>
<url-pattern>/Target05Servleturl-pattern>
filter-mapping>
<filter-mapping>
<filter-name>TargetChain02Filterfilter-name>
<url-pattern>/Target05Servleturl-pattern>
filter-mapping>
<filter-mapping>
<filter-name>TargetChain01Filterfilter-name>
<url-pattern>/Target05Servleturl-pattern>
filter-mapping>