@[toc]
一、Filter1.1 Filter概述Filter 表示过滤器,是的 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
过滤器可以要求资源拦截从而实现一些特殊功能。
如下图所示,浏览器可以访问服务器上的所有资源(servlet、jsp、html等)
在访问这些资源之前,过滤器可以被拦截,也就是说,它将在访问资源之前通过 Filter,如下图
拦截器拦截后能做什么功能?
一般来说,过滤器完成一些通用操作。例如,每个资源都需要编写一些代码来完成一个功能。我们不能在每个资源中编写这样的代码。此时,我们可以在过滤器中编写这些代码,因为我们要求每个资源通过过滤器。
也可以做过滤器 统一编码处理
、 敏感字符处理
等等…
进行 Filter
实现开发分为以下三个步骤
- 定义类,实现 Filter接口,并重写所有方法
- Filter拦截资源的配置路径:在类别中定义
@WebFilter
注解。注解。注解value
属性值/*
这意味着拦截所有资源 - 在dofilter方法中输出一个句子并放行
1.3 Filter执行流程在上述代码中
chain.doFilter(request,response);
也就是说,放行,也就是说,让它访问应该访问的资源。
使用过滤器的过程如上图所示,我们通过以下问题来研究过滤器的执行过程:
- 放行后访问相应的资源,资源访问完成后会回到Filter吗?从上图可以看出,肯定 会 回到Filter
- 如果回到Filter,是重头执行还是放行后的逻辑?如果是重头执行,就意味着
放行前逻辑
它将被执行两次,当然不会这样设计;因此,访问资源后,它将返回放行后逻辑
,执行这部分代码。
通过以上说明,我们可以总结Filter的执行流程如下:
在未来,我们可以在放行前处理请求处理的代码,如果在请求完成资源后处理响应的数据,我们可以在放行后进行逻辑辑处理。
1.4 Filter拦截路径配置拦截路径表示 Filter 拦截要求的资源并使用哪些资源 @WebFilter
配置注释。例如:@WebFilter(“拦截路径”)
拦截路径有以下四种配置方式:
- 拦截具体资源:/index.jsp:只有访问index.jsp才会被拦截
- 目录拦截://user/*:访问/user下的所有资源都将被拦截
- 拦截后缀名:*.jsp:访问后缀称为jsp的资源将被拦截
- 所有拦截://*:访问所有资源将被拦截
通过对上述拦截路径的研究,我们将发现拦截路径的配置方法和 Servlet
要求资源路径配置相同,但含义不同。
过滤器链是指可以配置多个过滤器的Web应用程序,称为过滤器链。
下图是一个过滤器链,我们学习过滤器链主要是学习过滤器链执行的过程
按照以下流程执行上图中的过滤器链:
- 执行
Filter1
放行前逻辑代码 - 执行
Filter1
的放行代码 - 执行
Filter2
放行前逻辑代码 - 执行
Filter2
的放行代码 - 访问到资源
- 执行
Filter2
释放后的逻辑代码 - 执行
Filter1
释放后的逻辑代码
上述过程串起来就像一条链子,故称过滤器链。
1.5.2 代码演示- 编写第一个过滤器
FilterDemo
,所有资源都被配置成拦截
@WebFilter(/*)public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //1. 放行前,对 处理request数据 System.out.println("1.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 处理数据 System.out.println("3.FilterDemo..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { }}
- 编写第二个过滤器
Filterdemo2
,所有资源的配置拦截
@WebFilter(/*)public class Filterdemo2 implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //1. 放行前,对 处理request数据 System.out.println("2.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 处理数据 System.out.println("4.FilterDemo..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { }}
- 修改
hello.jsp
脚本在页面中的输出语句
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h1>hello JSP~</h1> <% System.out.println("3.hello jsp"); %></body></html>
- 启动服务器,输入浏览器
http://localhost/filter-demo/hello.jsp
在控制台进行测试,打印内容如下
从结果可以看出,它确实是按照我们之前提到的执行过程执行的。
1.5.3 问题为什么上述代码首先执行? FilterDemo
,后执行 Filterdemo2
呢?
我们现在使用注释配置Filter,这种配置的优先级是根据过滤器类名(字符串)的自然排序。
例如,有以下两个名称的过滤器 : BFilterDemo
和 AFilterDemo
。那一定是 AFilterDemo
先执行过滤器。
- Listener 表示监听器,是的 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
- 监控器可以监控
application
,session
,request
当添加修改和删除属性时,三个对象创建、销毁或自动执行代码的功能组件。request 和 session 我们已经学会了。和application
是ServletContext
类型对象。ServletContext
代表整个web应用程序,tomcat将在服务器启动时自动创建对象。当服务器关闭时,对象将自动销毁。
JavaWeb 提供8个监听器:
这里面只有 ServletContextListener
我们以后会接触到这个监听器,ServletContextListener
是用来监听 ServletContext
对象的创建和销毁。
ServletContextListener
接口中有以下两种方法
void contextInitialized(ServletContextEvent sce)
:ServletContext
创建对象将自动执行的方法void contextDestroyed(ServletContextEvent sce)
:ServletContext
当对象被销毁时,该方法将自动执行
我们只演示一下 ServletContextListener
监听器
- 定义一个类,实现它
ServletContextListener
接口 - 重写所有抽象方法
- 使用
@WebListener
进行配置
代码如下:
@WebListenerpublic class ContextLoaderListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { ///加载资源 System.out.println("ContextLoaderListener..."); } @Override public void contextDestroyed(ServletContextEvent sce) { ///释放资源 }}
启动服务器可以在启动日志信息中看到 contextInitialized()
方法输出的内容也说明了 ServletContext
当服务器启动时,创建了对象。