首页 > 解决方案 > 如何在 Spring Boot 中仅使用一个拦截器处理所有传入请求

问题描述

我从几天开始一直在做spring boot,现在我想对所有传入的请求都有安全拦截器。在学习教程时,我发现有一个带有@Component注释的类,它实现HandlerInterceptor

@Component
public class ProductServiceInterceptor implements HandlerInterceptor {
   @Override
   public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

      return true;
   }
   @Override
   public void postHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler, 
      ModelAndView modelAndView) throws Exception {}

   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
      Object handler, Exception exception) throws Exception {}
}

然后必须InterceptorRegistry使用WebMvcConfigurerAdapterlike注册此拦截器

@Component
public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {
   @Autowired
   ProductServiceInterceptor productServiceInterceptor;

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(productServiceInterceptor);
   }
}

但我在本教程中感到困惑,拦截器仅用于一项服务,即Products,我的问题是如何拥有一个single interceptor class which will intercept all the incoming requests irrespective of any controller path

标签: spring-bootinterceptor

解决方案


如果您想保护您的应用程序,您可能需要查看Spring Security项目。

要实现您想要做的事情,您需要使用FilterFilterRegistrationBean

过滤器将拦截来自您在注册 bean 中定义的路径的每个请求和响应。

过滤器javadoc:

每次由于客户端对链末端资源的请求,请求/响应对通过链时,容器都会调用 Filter 的 doFilter 方法。传入此方法的 FilterChain 允许 Filter 将请求和响应传递给链中的下一个实体。此方法的典型实现将遵循以下模式:

  1. 检查请求
  2. 可以选择使用自定义实现包装请求对象以过滤内容或标题以进行输入过滤
  3. 可以选择使用自定义实现包装响应对象以过滤内容或标题以进行输出过滤
  4. a) 使用 FilterChain 对象 (chain.doFilter()) 调用链中的下一个实体,
  5. b) 或不将请求/响应对传递给过滤器链中的下一个实体以阻止请求处理
  6. 调用过滤器链中的下一个实体后,直接在响应上设置标头。

下面是一个过滤来自根 ("/*") 路径的所有请求的示例。

package com.example.demo;

import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

  private static final Logger log = LoggerFactory.getLogger(FilterConfig.class);

  @Bean
  public FilterRegistrationBean<Filter> registrationBean(Filter sampleFilter) {
    FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();

    bean.setFilter(sampleFilter);
    bean.addUrlPatterns("/*");

    return bean;
  }

  @Bean
  public Filter sampleFilter() {
    return (request, response, filterChain) -> {
      HttpServletRequest servletRequest = (HttpServletRequest) request;
      log.info(
          "Request URI : {}",
          servletRequest.getRequestURI());

      filterChain.doFilter(request, response);
      log.info(
          "After filtering the request : {}",
          servletRequest.getRequestURI());

    };
  }

}

推荐阅读