Spring Boot过滤器是构建Web应用程序的重要组成部分,本文我们将讨论以下几个问题:
- 什么是过滤器?
- 为什么我们需要过滤器?
- 在Spring Boot应用程序中添加过滤器的不同方法
- 如何使用特定的URL模式注册过滤器
它们允许您拦截请求和响应,以便应用自定义逻辑,例如身份验证、日志记录或修改请求/响应对象。
过滤器简介
过滤器是Java Servlet API的一部分,它们允许您预处理和后处理请求和响应。
创建过滤器
要在Spring Boot中创建过滤器,您可以实现javax.servlet.Filter
接口或扩展OncePerRequestFilter
类。OncePerRequestFilter
确保您的过滤器每个请求只执行一次。
@RestController
@RequestMapping("/customer")
public class CustomerController {
@GetMapping
public String getMessage(){
return "welcome to filter session";
}
}
@Component
@Slf4j
public class MessageFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("[MessageFilter] - Inside doFilter method");
log.info("Local Port : " + request.getLocalPort());
log.info("Server Name : " + request.getServerName());
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("Method Name : " + httpServletRequest.getMethod());
log.info("Request URI : " + httpServletRequest.getRequestURI());
log.info("Servlet Path : " + httpServletRequest.getServletPath());
chain.doFilter(request, response);
}
}
要测试此过滤器,请访问http://localhost:9898/customer
过滤器的顺序
过滤器的应用顺序可以通过@Order
注解
@Component
@Slf4j
@Order(2)
public class MessageFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("[MessageFilter] - Inside doFilter method");
log.info("Local Port : " + request.getLocalPort());
log.info("Server Name : " + request.getServerName());
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("Method Name : " + httpServletRequest.getMethod());
log.info("Request URI : " + httpServletRequest.getRequestURI());
log.info("Servlet Path : " + httpServletRequest.getServletPath());
chain.doFilter(request, response);
}
}
@Component
@Slf4j
@Order(1)
public class ProductFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("[ProductFilter] - Inside doFilter method");
log.info("Local Port : " + request.getLocalPort());
log.info("Server Name : " + request.getServerName());
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("Method Name : " + httpServletRequest.getMethod());
log.info("Request URI : " + httpServletRequest.getRequestURI());
log.info("Servlet Path : " + httpServletRequest.getServletPath());
chain.doFilter(request, response);
}
}
如果您只想打印MessageFilter并跳过ProductFilter
要在访问/customer
API时仅显示MessageFilter
的日志,您需要有条件地绕过ProductFilter
对/customer
端点的过滤。您可以通过修改ProductFilter
来跳过特定端点的过滤来实现这一点。
@Component
@Slf4j
@Order(1) // 确保此过滤器在MessageFilter之前执行
public class ProductFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestURI = httpServletRequest.getRequestURI();
if ("/customer".equals(requestURI)) {
chain.doFilter(request, response);
return; // 跳过过滤器的其余部分
}
log.info("[ProductFilter] - Inside doFilter method");
log.info("Local Port : " + request.getLocalPort());
log.info("Server Name : " + request.getServerName());
log.info("Method Name : " + httpServletRequest.getMethod());
log.info("Request URI : " + requestURI);
log.info("Servlet Path : " + httpServletRequest.getServletPath());
chain.doFilter(request, response);
}
}
注册过滤器
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<messagefilter> loggingFilter(){
FilterRegistrationBean<messagefilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MessageFilter());
registrationBean.addUrlPatterns("/customer/*"); // 如果需要,指定URL模式
return registrationBean;
}
}
OncePerRequestFilter
public class ProductFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
log.info("[ProductFilter] - Inside doFilter method");
log.info("Local Port : " + request.getLocalPort());
log.info("Server Name : " + request.getServerName());
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("Method Name : " + httpServletRequest.getMethod());
log.info("Request URI : " + httpServletRequest.getRequestURI());
log.info("Servlet Path : " + httpServletRequest.getServletPath());
filterChain.doFilter(request, response);
}
}
要测试此过滤器,请访问: http://localhost:9898/product
> 欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源</messagefilter></messagefilter>