Javaweb之Filter和Listener

本文介绍了JavaWeb的过滤器Filter,作为三大组件之一,它能拦截资源请求以实现特定功能。Filter的生命周期包括init、doFilter和destroy方法,doFilter是核心,通过FilterChain放行请求。过滤器链按照类名顺序执行。监听器Listener则能监听ServletContext、session和request的事件,例如ServletContextListener在web应用启动和关闭时自动执行代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Filter

1.1 Filter概述

Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。Servlet 我们之前都已经学习过了,Filter和Listener 我们今天都会进行学习。

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

如下图所示,浏览器可以访问服务器上的所有的资源(servlet、jsp、html等)
在这里插入图片描述
而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter,如下图
在这里插入图片描述

1.2Filter快速入门

拦截器拦截到后可以做什么功能呢?

过滤器一般完成一些通用的操作 比如每个资源都要写一些代码完成某个功能,我们总不能在每个资源中写这样的代码吧,而此时我们可以将这些代码写在过滤器中,因为请求每一个资源都要经过过滤器。

我们之前做的品牌数据管理的案例中就已经做了登陆的功能,而如果我们不登录能不能访问到数据呢?我们可以在浏览器直接访问首页 ,可以看到 查询所有 的超链接
在这里插入图片描述

1.init和destroy是生命周期有关的方法 doFilter是过滤器的核心方法将来每次访问过滤器都会访问这个方法
2.其中Filter的路径不是资源的访问路径而是要拦截资源的路径 过滤器是拦截对资源访问的请求的
3.dofilter中做了一些操作然后放走人家 然后让他继续访问后续资源 chain.doFilter(request,response)
快速入门webFilter里面写的是拦截路径

@WebFilter("/*")
public class FilterDemo implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo...");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

在doFilter方法中输出一句话,并放行

在这里插入图片描述

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

1.3 Filter执行流程

在这里插入图片描述

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

  • 放行后访问对应资源,资源访问完成后,还会回到Filter中吗?

    从上图就可以看出肯定 回到Filter中

  • 如果回到Filter中,是重头执行还是执行放行后的逻辑呢?

    如果是重头执行的话,就意味着 放行前逻辑 会被执行两次,肯定不会这样设计了;所以访问完资源后,会回到 放行后逻辑,执行该部分代码。
    执行逻辑为:在这里插入图片描述
    首先执行Filter中放行前的逻辑 放行 访问web资源 响应回来执行放行后逻辑

1.4 Filter拦截路径配置

拦截路径表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter 注解进行配置。如:@WebFilter("拦截路径")

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

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

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("2.hello jsp");
    %>

</body>
</html>

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h1>index JSP~</h1>

    <%
        System.out.println("index jsp");
    %>

</body>
</html>

1.5 过滤器链

1.5.1 概述

过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。

如下图就是一个过滤器链,我们学习过滤器链主要是学习过滤器链执行的流程
在这里插入图片描述

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

  1. 执行 Filter1 的放行前逻辑代码
  2. 执行 Filter1 的放行代码
  3. 执行 Filter2 的放行前逻辑代码
  4. 执行 Filter2 的放行代码
  5. 访问到资源
  6. 执行 Filter2 的放行后逻辑代码
  7. 执行 Filter1 的放行后逻辑代码

以上流程串起来就像一条链子,故称之为过滤器链。
FilterDemo.java

@WebFilter("/*")
public class FilterDemo implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.放行前 对request数据进行处理 同时response是没有数据的
        System.out.println("1.FilterDemo...");
        //放行 的时候就用方形前处理完成request数据
        filterChain.doFilter(servletRequest, servletResponse);

        //3.放行后 等资源访问完成 response对象内部才有数据 所以放行后才对资源进行处理
        System.out.println("5.FilterDemo");
    }

    @Override
    public void destroy() {

    }
}

FilterDemo2.java

@WebFilter("/*")
public class FilterDemo2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.放行前 对request数据进行处理 同时response是没有数据的
        System.out.println("2.FilterDemo...");
        //放行 的时候就用方形前处理完成request数据
        filterChain.doFilter(servletRequest, servletResponse);

        //3.放行后 等资源访问完成 response对象内部才有数据 所以放行后才对资源进行处理
        System.out.println("4.FilterDemo");
    }

    @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>

在这里插入图片描述
这两个过滤器看似没有任何关系 到底如何执行先后
这里先执行Filter1的代码 再执行Filter2的代码 注解配置的Filter,优先级按照过滤器类名的自然排序 也就是FilterDemo和FilterDemo2的类名一个个字符进行比较 注解配置的Filter,优先级按照过滤器类名(字符串)的自然排序

2.Listener

2.1 概述

  • Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

  • 监听器可以监听就是在 applicationsessionrequest 三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

    request 和 session 我们学习过。而 applicationServletContext 类型的对象。

    ServletContext 代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象。

2.2 分类

JavaWeb 提供了8个监听器:
在这里插入图片描述
这里面只有 ServletContextListener 这个监听器后期我们会接触到,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。

ServletContextListener 接口中有以下两个方法

  • void contextInitialized(ServletContextEvent sce)ServletContext 对象被创建了会自动执行的方法
  • void contextDestroyed(ServletContextEvent sce)ServletContext 对象被销毁时会自动执行的方法

2.3 代码演示

sevletContext对象代表web应用程序创建 对象就被创建了说明web应用加载成功

我们只演示一下 ServletContextListener 监听器

  • 1.定义一个类,实现ServletContextListener 接口
  • 2.重写所有的抽象方法
  • 3.使用 @WebListener 进行配置

代码如下:

@WebListener
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //加载资源
        System.out.println("ContextLoaderListener");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //释放资源
    }
}

Connected to server
[2023-03-11 11:05:16,322] Artifact brand-demo:war exploded: Artifact is being deployed, please wait…
11-Mar-2023 23:05:17.070 信息 [RMI TCP Connection(2)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。
ContextLoaderListener

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值