一文详解Filter类源码和应用

背景

在日常开发中,经常会有需要统一对请求做一些处理,常见的比如记录日志、权限安全控制、响应处理等。此时,ServletApi中的Filter类,就可以很方便的实现上述效果。

Filter类 是一个接口,属于 Java Servlet API 的一部分,主要用于在 Servlet 处理请求之前或之后执行过滤任务。Filter 的作用是拦截请求和响应,从而实现一些通用的功能,而无需修改 Servlet 或 JSP 的代码。

Filter源码

从Filter的源码,可以看出:Filter是一个接口,Filter 的生命周期由三个主要方法控制。分别是init / doFilter / destory方法。

接下来具体讲一下,这三个方法的作用:

  1. init(FilterConfig filterConfig)初始化 Filter,在 Filter 被加载时调用一次。一般用于加载资源、初始化配置信息等。(从入参FilterConfig看出,可以获得上下文、请求参数等信息

  2. doFilter(ServletRequest request, ServletResponse response, FilterChain chain):核心方法,用于处理一些具体的过滤逻辑。(可以获得并处理request, response信息

    1. 在调用 chain.doFilter(request, response) 之前,可以对请求进行预处理。

    2. 在调用 chain.doFilter(request, response) 之后,可以对响应进行后处理。

    3. 如果不想让请求继续向下传递,可以不调用 chain.doFilter(request, response)

  3. destroy():销毁 Filter,在 Filter 被卸载时调用一次。一般用于释放资源、清理等逻辑。

Filter场景

Filter 的核心功能是拦截请求和响应,从而实现以下功能:

  • 日志记录:记录请求的详细信息,如请求的 URL、参数、时间戳等。

  • 权限检查:验证用户是否具有访问特定资源的权限。

  • 响应修改:修改响应的内容或格式,例如添加 HTTP 响应头。

  • 资源管理:限制对某些资源的访问频率或次数。

Filter使用示例

例如,我们可以在每次请求中,记录请求的耗时时长,并在注入TRACE_ID参数,以方便后续根据日志,进行链路追踪。

java 复制代码
import javax.servlet.*;
import java.io.IOException;

public class LoggingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LoggingFilter initialized");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        String traceId = request.getHeader("TRACE_ID");
        if (StrUtil.isBlank(traceId)) {
            traceId = UUID.randomUUID().toString().toLowerCase().replaceAll("-", "");
        }

        try {
            //设置链路ID
            MDC.put("TRACE_ID", traceId);
            response.addHeader("TRACE_ID",traceId);

            // 调用下一个 Filter 或 Servlet
            chain.doFilter(request, response);
        }finally {
            MDC.remove("traceId");com.zwy.discover.mybatis.LogConfig.remove();
        }


        long endTime = System.currentTimeMillis();
        //打印请求耗时
        System.out.println("Request processed in " + (endTime - startTime) + " ms");
    }

    @Override
    public void destroy() {
        System.out.println("LoggingFilter destroyed");
    }
}

Filter配置方式

  • 使用 web.xml 配置
XML 复制代码
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.LoggingFilter</filter-class>
    <init-param>
        <param-name>param1</param-name>
        <param-value>value1</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>LoggingFilter</filter-name>
    <!-- 拦截所有请求 -->
    <url-pattern>/*</url-pattern> 
</filter-mapping>
  • 使用注解配置(Servlet 3.0+)

从 Servlet 3.0 开始,可以使用 @WebFilter 注解来定义 Filter,无需在 web.xml 中配置。

java 复制代码
@WebFilter(filterName = "LoggingFilter", urlPatterns = "/*")
public class LoggingFilter implements Filter {
    // Filter 方法实现
}
相关推荐
把马铃薯变成土豆11 天前
前端Stripe跨境支付对接感想
前端·源码
源码宝16 天前
拿来即改的云HIS源码:前端BootStrap+LayUI,后端SpringBoot,数据库MySQL+MyCat
java·源码·his系统·云技术·his源码·医院信息系统源码
幽络源小助理16 天前
2026最新写真图片视频打赏系统源码_全开源无加密_幽络源源码
开源·源码·php源码
幽络源小助理17 天前
苹果CMS觅知ART弹幕播放器_MizhiPlayer全新UI-幽络源源码网
开源·源码·php源码
程序猿阿越18 天前
AutoMQ源码(一)读、写、Compaction
java·后端·源码
贾艺驰19 天前
实战Android Framework: 新增一个系统服务
android·源码
VX_BYSJ834120 天前
【关注可白嫖源码】--17214基于Web的旅游信息交互网站设计与实现(案例分析)
源码·毕设·计算机毕业设计·大作业·毕设定制·程序定制·毕设代做
源码宝22 天前
智能随访系统源码,技术架构设计:Spring Boot + Vue.js + 微服务实战
java·人工智能·源码·随访系统·智能随访·随访系统成品源码
甜瓜看代码25 天前
SystemUI 启动与组成机制
android·源码·源码阅读
源码宝1 个月前
基于SpringCloud+UniApp的智慧工地云平台整体架构设计与实现
java·人工智能·spring cloud·源码·智慧工地·云平台