过滤器与监听器学习

在 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),在线人数都会实时更新。


三、总结

组件 作用 常见场景
过滤器 拦截请求,进行预处理/后处理 编码过滤、权限校验、日志记录
监听器 监听对象变化,执行相应逻辑 在线人数统计、资源初始化、日志监控
相关推荐
北漂Zachary9 分钟前
四大编程语言终极对比
android·java·php·laravel
小江的记录本16 分钟前
【网络安全】《网络安全常见攻击与防御》(附:《六大攻击核心特性横向对比表》)
java·网络·人工智能·后端·python·安全·web安全
一个人旅程~42 分钟前
旧电脑的“拯救者”?Linux Mint20.3是怎样适配软件硬件以及兼顾兼容与性能的平衡的?
linux·经验分享·电脑
墨黎芜44 分钟前
ArcGIS从入门到精通——地图符号、注记的初步使用
学习·arcgis·信息可视化
小李云雾1 小时前
FastAPI重要知识点---中间件(Middleware)
学习·程序人生·中间件·fastapi·middleware
.Cnn1 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
小夏子_riotous1 小时前
Docker学习路径——3、常用命令
linux·运维·服务器·学习·docker·容器·centos
嗑嗑嗑瓜子的猫1 小时前
Java!它值得!
java·开发语言
STLearner1 小时前
WSDM 2026 | 时间序列(Time Series)论文总结【预测,表示学习,因果】
大数据·论文阅读·人工智能·深度学习·学习·机器学习·数据挖掘
redaijufeng2 小时前
网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。
爬虫·学习·selenium