背景
在日常开发中,经常会有需要统一对请求做一些处理,常见的比如记录日志、权限安全控制、响应处理等。此时,ServletApi中的Filter类,就可以很方便的实现上述效果。
Filter类
是一个接口,属于 Java Servlet API 的一部分,主要用于在 Servlet 处理请求之前或之后执行过滤任务。Filter
的作用是拦截请求和响应,从而实现一些通用的功能,而无需修改 Servlet 或 JSP 的代码。
Filter源码
从Filter的源码,可以看出:Filter是一个接口,Filter
的生命周期由三个主要方法控制。分别是init / doFilter / destory方法。
接下来具体讲一下,这三个方法的作用:
-
init(FilterConfig filterConfig):
初始化Filter
,在Filter
被加载时调用一次。一般用于加载资源、初始化配置信息等。(从入参FilterConfig看出,可以获得上下文、请求参数等信息
) -
doFilter(ServletRequest request, ServletResponse response, FilterChain chain):核心方法,用于处理一些具体的过滤逻辑。(可以获得并处理request, response信息)
-
在调用
chain.doFilter(request, response)
之前,可以对请求进行预处理。 -
在调用
chain.doFilter(request, response)
之后,可以对响应进行后处理。 -
如果不想让请求继续向下传递,可以不调用
chain.doFilter(request, response)
。
-
-
destroy():
销毁Filter
,在Filter
被卸载时调用一次。一般用于释放资源、清理等逻辑。
Filter场景
Filter
的核心功能是拦截请求和响应,从而实现以下功能:
-
日志记录:记录请求的详细信息,如请求的 URL、参数、时间戳等。
-
权限检查:验证用户是否具有访问特定资源的权限。
-
响应修改:修改响应的内容或格式,例如添加 HTTP 响应头。
-
资源管理:限制对某些资源的访问频率或次数。
Filter使用示例
例如,我们可以在每次请求中,记录请求的耗时时长,并在注入TRACE_ID参数,以方便后续根据日志,进行链路追踪。
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
配置
<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
中配置。
@WebFilter(filterName = "LoggingFilter", urlPatterns = "/*")
public class LoggingFilter implements Filter {
// Filter 方法实现
}
标签:请求,request,Filter,doFilter,源码,LoggingFilter,response,详解 From: https://blog.csdn.net/weixin_40709965/article/details/145311153