过滤器与监听器学习

在 JavaWeb 开发中,过滤器(Filter)监听器(Listener) 是两大核心组件。它们不直接处理业务逻辑,却在幕后默默支撑着整个 Web 应用的运行。今天我们就来聊聊它们的作用、用法以及应用场景。

一、过滤器(Filter)

1. 什么是过滤器?

过滤器是 JavaWeb 的三大组件之一(另外两个是 Servlet 和 Listener)。它主要用于拦截请求,可以在请求到达 Servlet 之前进行预处理,也可以在响应返回客户端之后进行后处理。

工作流程

用户请求 → 过滤器(判断是否放行)→ Servlet(处理请求)→ 返回响应 → 过滤器(后处理)→ 客户端

如果过滤器不放行,请求将无法到达 Servlet。

2. 快速入门

步骤1:实现 Filter 接口
java 复制代码
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("过滤器执行前");
        chain.doFilter(request, response); // 放行
        System.out.println("过滤器执行后");
    }

    @Override
    public void destroy() {}
}
步骤2:在 web.xml 中配置
XML 复制代码
<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>cn.tx.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这样,所有请求都会被该过滤器拦截。

3. 过滤器生命周期

  • init():服务器启动时执行,只执行一次。

  • doFilter():每次请求都会执行。

  • destroy():服务器关闭时执行,只执行一次。

4. 过滤器链与执行顺序

多个过滤器可以作用于同一个目标资源,执行顺序由 web.xml 中的配置顺序决定。

例如:

XML 复制代码
xml

<filter-mapping>
    <filter-name>filterA</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>filterB</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

执行结果:

XML 复制代码
filterA 被执行
filterB 被执行
目标资源执行
filterB 执行完毕
filterA 执行完毕

5. 过滤器常见应用场景

  • 请求编码处理:统一设置请求和响应的字符编码。

  • 用户权限校验:判断用户是否登录,是否具有访问权限。

  • 日志记录:记录请求的访问时间、IP 等。

  • 数据压缩:对响应内容进行压缩处理。

6. 解决 POST 请求中文乱码

过滤器代码:

java 复制代码
public class EncodeFilter implements Filter {
    private String encode;

    @Override
    public void init(FilterConfig config) throws ServletException {
        encode = config.getInitParameter("encode");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        req.setCharacterEncoding(encode);
        res.setContentType("text/html;charset=" + encode);
        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {}
}

配置:

XML 复制代码
<filter>
    <filter-name>encodeFilter</filter-name>
    <filter-class>cn.tx.filter.EncodeFilter</filter-class>
    <init-param>
        <param-name>encode</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodeFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这样,所有请求的编码都会统一为 UTF-8,解决了中文乱码问题。


二、监听器(Listener)

监听器用于监听 JavaWeb 中三大域对象(ServletContextHttpSessionServletRequest)的创建、销毁及属性变化。

1. 常用监听器

监听器 作用
ServletContextListener 监听应用启动和关闭
HttpSessionListener 监听 Session 创建和销毁
ServletRequestListener 监听请求创建和销毁

2. 使用示例

实现多个监听接口:

java 复制代码
public class MyListener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("应用启动");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("应用关闭");
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("Session 创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session 销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("请求开始");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("请求结束");
    }
}

配置:

XML 复制代码
<listener>
    <listener-class>cn.tx.listener.MyListener</listener-class>
</listener>

3. 统计在线人数

通过 HttpSessionListener 监听 Session 的创建和销毁,实时统计在线人数。

监听器代码:

java 复制代码
public class OnlineCountListener implements HttpSessionListener {
    private Integer count = 0;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        count = (Integer) context.getAttribute("count");
        context.setAttribute("count", ++count);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        count = (Integer) context.getAttribute("count");
        context.setAttribute("count", --count);
    }
}

JSP 中显示:

html 复制代码
当前在线人数:${count}

这样,每次用户访问网站(创建 Session)或退出(销毁 Session),在线人数都会实时更新。


三、总结

组件 作用 常见场景
过滤器 拦截请求,进行预处理/后处理 编码过滤、权限校验、日志记录
监听器 监听对象变化,执行相应逻辑 在线人数统计、资源初始化、日志监控
相关推荐
LegendNoTitle2 小时前
计算机三级等级考试 网络技术 选择题考点详细梳理
服务器·前端·经验分享·笔记·php
炽烈小老头2 小时前
【 每天学习一点算法 2026/03/23】数组中的第K个最大元素
学习·算法·排序算法
程序员小假2 小时前
我们来说一下 b+ 树与 b 树的区别
java·后端
LaughingZhu2 小时前
Product Hunt 每日热榜 | 2026-03-23
数据库·人工智能·经验分享·神经网络·chatgpt
Meepo_haha3 小时前
Spring Boot 条件注解:@ConditionalOnProperty 完全解析
java·spring boot·后端
sheji34163 小时前
【开题答辩全过程】以 基于springboot的房屋租赁系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
木井巳3 小时前
【递归算法】子集
java·算法·leetcode·决策树·深度优先
Oll Correct4 小时前
实验八:验证以太网交换机的生成树协议STP
网络·笔记