FilterRegistrationBean是Spring框架中的一个重要组件,它的作用是注册和管理过滤器。在Web应用程序中,过滤器是用于拦截HTTP请求和响应的组件。FilterRegistrationBean可以通过Java代码配置,也可以通过XML配置文件进行配置。
FilterRegistrationBean的工作原理是在Spring应用程序启动时,自动扫描并注册所有配置的过滤器。这些过滤器可以拦截HTTP请求和响应,并执行一些预定义的操作。例如,过滤器可以检查请求参数、修改请求头、记录请求日志等。
FilterRegistrationBean的使用非常灵活,可以根据具体的需求进行配置。例如,可以指定过滤器的名称、URL模式、执行顺序等。
上篇文章针对全局日志的文章https://blog.51cto.com/u_16174475/7335078
针对全局的日志traceId处理,就使用了FilterRegistrationBean注册LogFilter
package com.study.springbootplus.config;
import com.study.springbootplus.utils.ThreadMdcUtil;
import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
ThreadMdcUtil.setTraceIdIfAbsent();
try {
filterChain.doFilter(request, response);
} finally {
response.addHeader(ThreadMdcUtil.TRACE_ID, MDC.get(ThreadMdcUtil.TRACE_ID));
ThreadMdcUtil.remove();
}
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new LogFilter());
filterRegistrationBean.setOrder(Integer.MIN_VALUE);
return filterRegistrationBean;
}
FilterRegistrationBean还支持许多其他属性。例如,可以指定过滤器的初始化参数、异步支持、servlet名称等。以下是一些常用的属性:
有些filter想要排除部分uri,使用FilterRegistrationBean 该怎么操作呢?
FilterRegistrationBean 里面的方法比如addUrlPatterns,只能用来指定uri,并没有其他方法来进行过滤uri,所以只能在继承OncePerRequestFilter的LogFilter里面实现
OncePerRequestFilter有个shouldNotFilter方法,用来排除uri,如果需要排除的uri是固定的话就只需要在方法里面加上排除的uri:
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String requestURI = request.getRequestURI();
return requestURI.startsWith("/actuator")
|| requestURI.startsWith("/captcha");
}
如果是多个项目使用,不同项目需要指定不同url,那就可以在LogFilter定义一个List,然后在初始化的时候set需要过滤的uri就可以:
package com.study.springbootplus.config;
import com.google.common.collect.Lists;
import com.study.springbootplus.utils.ThreadMdcUtil;
import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class LogFilter extends OncePerRequestFilter {
private static List<String> excludes = Lists.newArrayList();
public static void setExcludes(List<String> excludes) {
LogFilter.excludes = excludes;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
ThreadMdcUtil.setTraceIdIfAbsent();
try {
filterChain.doFilter(request, response);
} finally {
response.addHeader(ThreadMdcUtil.TRACE_ID, MDC.get(ThreadMdcUtil.TRACE_ID));
ThreadMdcUtil.remove();
}
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return excludes.contains(request.getRequestURI());
}
}
在使用的地方:
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
LogFilter logFilter = new LogFilter();
logFilter.setExcludes(Lists.newArrayList("/aaa", "/bb"));
filterRegistrationBean.setFilter(logFilter);
filterRegistrationBean.setOrder(Integer.MIN_VALUE);
return filterRegistrationBean;
}