当前位置: 首页 > 图灵资讯 > 技术篇> JavaWeb中Filter&Listener的神奇作用

JavaWeb中Filter&Listener的神奇作用

来源:图灵教育
时间:2023-05-22 09:19:19

@[toc]

一、Filter1.1 Filter概述

Filter 表示过滤器,是的 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

过滤器可以要求资源拦截从而实现一些特殊功能。

如下图所示,浏览器可以访问服务器上的所有资源(servlet、jsp、html等)

JavaWeb中Filter&Listener的神奇作用_System_02

在访问这些资源之前,过滤器可以被拦截,也就是说,它将在访问资源之前通过 Filter,如下图

JavaWeb中Filter&Listener的神奇作用_System_03

拦截器拦截后能做什么功能?

JavaWeb中Filter&Listener的神奇作用_ide_04

一般来说,过滤器完成一些通用操作。例如,每个资源都需要编写一些代码来完成一个功能。我们不能在每个资源中编写这样的代码。此时,我们可以在过滤器中编写这些代码,因为我们要求每个资源通过过滤器。

也可以做过滤器 统一编码处理敏感字符处理 等等…

1.2 Filter快速入门1.2.1 开发步骤

进行 Filter 实现开发分为以下三个步骤

  • 定义类,实现 Filter接口,并重写所有方法
  • Filter拦截资源的配置路径:在类别中定义 @WebFilter 注解。注解。注解 value 属性值 /* 这意味着拦截所有资源
  • 在dofilter方法中输出一个句子并放行

在上述代码中 chain.doFilter(request,response); 也就是说,放行,也就是说,让它访问应该访问的资源。

1.3 Filter执行流程

JavaWeb中Filter&Listener的神奇作用_System_05

使用过滤器的过程如上图所示,我们通过以下问题来研究过滤器的执行过程:

  • 放行后访问相应的资源,资源访问完成后会回到Filter吗?从上图可以看出,肯定 回到Filter
  • 如果回到Filter,是重头执行还是放行后的逻辑?如果是重头执行,就意味着 放行前逻辑 它将被执行两次,当然不会这样设计;因此,访问资源后,它将返回 放行后逻辑,执行这部分代码。

通过以上说明,我们可以总结Filter的执行流程如下:

JavaWeb中Filter&Listener的神奇作用_System_06

在未来,我们可以在放行前处理请求处理的代码,如果在请求完成资源后处理响应的数据,我们可以在放行后进行逻辑辑处理。

JavaWeb中Filter&Listener的神奇作用_System_07

1.4 Filter拦截路径配置

拦截路径表示 Filter 拦截要求的资源并使用哪些资源 @WebFilter 配置注释。例如:@WebFilter(“拦截路径”)

拦截路径有以下四种配置方式:

  • 拦截具体资源:/index.jsp:只有访问index.jsp才会被拦截
  • 目录拦截://user/*:访问/user下的所有资源都将被拦截
  • 拦截后缀名:*.jsp:访问后缀称为jsp的资源将被拦截
  • 所有拦截://*:访问所有资源将被拦截

通过对上述拦截路径的研究,我们将发现拦截路径的配置方法和 Servlet 要求资源路径配置相同,但含义不同。

1.5 过滤器链1.5.1 概述

过滤器链是指可以配置多个过滤器的Web应用程序,称为过滤器链。

下图是一个过滤器链,我们学习过滤器链主要是学习过滤器链执行的过程

JavaWeb中Filter&Listener的神奇作用_监听器_08

按照以下流程执行上图中的过滤器链:

JavaWeb中Filter&Listener的神奇作用_监听器_09

  1. 执行 Filter1 放行前逻辑代码
  2. 执行 Filter1 的放行代码
  3. 执行 Filter2 放行前逻辑代码
  4. 执行 Filter2 的放行代码
  5. 访问到资源
  6. 执行 Filter2 释放后的逻辑代码
  7. 执行 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,这种配置的优先级是根据过滤器类名(字符串)的自然排序。

例如,有以下两个名称的过滤器 : BFilterDemoAFilterDemo 。那一定是 AFilterDemo 先执行过滤器。

2.Listener2.1 概述
  • Listener 表示监听器,是的 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
  • 监控器可以监控 applicationsessionrequest 当添加修改和删除属性时,三个对象创建、销毁或自动执行代码的功能组件。request 和 session 我们已经学会了。和 applicationServletContext 类型对象。ServletContext 代表整个web应用程序,tomcat将在服务器启动时自动创建对象。当服务器关闭时,对象将自动销毁。
2.2 分类

JavaWeb 提供8个监听器:

JavaWeb中Filter&Listener的神奇作用_监听器_10

这里面只有 ServletContextListener 我们以后会接触到这个监听器,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。

ServletContextListener 接口中有以下两种方法

  • void contextInitialized(ServletContextEvent sce)ServletContext 创建对象将自动执行的方法
  • void contextDestroyed(ServletContextEvent sce)ServletContext 当对象被销毁时,该方法将自动执行
2.3 代码演示

我们只演示一下 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 当服务器启动时,创建了对象。