在 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 中三大域对象(ServletContext、HttpSession、ServletRequest)的创建、销毁及属性变化。
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),在线人数都会实时更新。
三、总结
| 组件 | 作用 | 常见场景 |
|---|---|---|
| 过滤器 | 拦截请求,进行预处理/后处理 | 编码过滤、权限校验、日志记录 |
| 监听器 | 监听对象变化,执行相应逻辑 | 在线人数统计、资源初始化、日志监控 |