过滤器与监听器学习

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

一、过滤器(Filter)

1. 什么是过滤器?

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

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

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

2. 快速入门

步骤1:实现 Filter 接口
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 中配置
<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

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

执行结果:

filterA 被执行
filterB 被执行
目标资源执行
filterB 执行完毕
filterA 执行完毕

5. 过滤器常见应用场景

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

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

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

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

6. 解决 POST 请求中文乱码

过滤器代码:

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() {}
}

配置:

<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. 使用示例

实现多个监听接口:

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("请求结束");
    }
}

配置:

<listener>
    <listener-class>cn.tx.listener.MyListener</listener-class>
</listener>

3. 统计在线人数

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

监听器代码:

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 中显示:

当前在线人数:${count}

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


三、总结

组件作用常见场景
过滤器拦截请求,进行预处理/后处理编码过滤、权限校验、日志记录
监听器监听对象变化,执行相应逻辑在线人数统计、资源初始化、日志监控

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值