无法为 Spring Boot 2 应用程序中的拦截器添加配置 WebMvcConfigurer

Posted

技术标签:

【中文标题】无法为 Spring Boot 2 应用程序中的拦截器添加配置 WebMvcConfigurer【英文标题】:Can't configure WebMvcConfigurer for interceptors addition in spring boot 2 application 【发布时间】:2019-10-05 22:48:57 【问题描述】:

我第一次尝试在我的 Spring Boot 应用程序中创建一个拦截器,但不知何故,它不是自动创建的,如教程中所述。

我尝试创建一个扩展 WebMvcConfigurerAdapter 类的 WebConfig 类并将其注释为 @Component 但它没有工作。我还尝试创建一个 WebConfig,它使用 @Configuration 和 @EnableWebMvc 注释实现 WebMvcConfigurer 接口,但它也没有工作。

当前的 WebConfig 类:

@Configuration
@EnableWebMvc
@ComponentScan("com.*")
public class WebConfig implements WebMvcConfigurer 


    public WebConfig() 
        super();
    

    @Autowired
    HandlerInterceptor headerModifierInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        System.out.println("------------------hi");
        registry.addInterceptor(headerModifierInterceptor);
    


应用类

@SpringBootApplication
@EnableWebSecurity
@ComponentScan(basePackages = "com.*")
@EntityScan("com")
public class CoreRestAPIApplication 

    public static void main(String[] args) 

        SpringApplication.run(CoreRestAPIApplication.class, args);

    

我的拦截器类:

@Component
public class RestTemplateHeaderModifierInterceptor
        implements HandlerInterceptor 

    @Autowired
    AuthUtil authUtil;

    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception 
        String resolvedToken = jwtTokenProvider.resolveToken(request);
        if (!StringUtils.isEmpty(resolvedToken)) 
            String updatedToken = jwtTokenProvider.createToken(jwtTokenProvider.getUsername(resolvedToken), jwtTokenProvider.getAuthentication(resolvedToken).getAuthorities());
            response.addHeader(authUtil.AUTH_HEADER_NAME, updatedToken);
        
    


【问题讨论】:

永远不要在 Spring Boot 中使用 EnableWebMvc。它禁用了 Spring Boot 完成的所有自动配置。此外,将自动装配拦截器的类型更改为 RestTemplateHeaderModifierInterceptor。最后,准确解释您期望发生什么,以及会发生什么。如果您遇到异常,请发布其完整且准确的堆栈跟踪。 @JBNizet 所以,我已经放弃了 EnableWebMvc 并更改了自动装配拦截器,但仍然没有任何反应。我正在尝试使用 Described 拦截器在每个授权请求后更新令牌,但不知何故,它甚至还没有被注册。我在 --------hi 打印和 registry.addInterceptor 和 spring 上设置了断点启动时还没有达到。 @ComponentScan(basePackages = "com.*" 应该是 @ComponentScan(basePackages = "com"。它需要一个包名。 com.* 不是包名。 【参考方案1】:

经过一番搜索,我发现我有一个注册的 WebMvcConfigurationSupport 配置。但是,如果有人正在寻找并希望使用拦截器修改标头,请勿为此使用拦截器,因为如果您返回 ResponseEntity 或您的控制器方法返回 @,spring 将无法很好地处理它响应体。 相反(至少对于我来说,每次收到有效请求时过滤和更新令牌)使用 doFilterInternal 方法将标头添加到响应中(或者如果您愿意,可以添加 cookie ..)这里是一个示例我做到了:

public class JwtTokenFilter extends OncePerRequestFilter 

  private JwtTokenProvider jwtTokenProvider;

  public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) 
    this.jwtTokenProvider = jwtTokenProvider;
  

  @Override
  protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException 
    String token = jwtTokenProvider.resolveToken(httpServletRequest);
    try 
      if (token != null && jwtTokenProvider.validateToken(token)) 
        Authentication auth = jwtTokenProvider.getAuthentication(token);
        SecurityContextHolder.getContext().setAuthentication(auth);
        if(!jwtTokenProvider.isExpired(token)) 
          httpServletResponse.setHeader("authKey", jwtTokenProvider.createToken(jwtTokenProvider.getUsername(token), auth.getAuthorities()));
        
      
     catch (ClientErrorException ex) 
      //this is very important, since it guarantees the models is not authenticated at all
      SecurityContextHolder.clearContext();
      httpServletResponse.sendError(ex.getStatus().value(), ex.getMessage());
      return;
    

    filterChain.doFilter(httpServletRequest, httpServletResponse);
  



【讨论】:

以上是关于无法为 Spring Boot 2 应用程序中的拦截器添加配置 WebMvcConfigurer的主要内容,如果未能解决你的问题,请参考以下文章

在Eclipse中的Spring Boot应用程序,配置为侦听端口XXXX的Tomcat连接器无法启动

无法覆盖 Spring Boot 应用程序的 Hazelcast.yaml 中的属性

Spring Boot 项目中的 Gradle 无法识别路径中的 Java jdk

无法将 spring-boot 2 服务连接到不同容器中的 mysql

Spring Boot 2.1.0 和 Java 11 上的 Spring Data Redis 无法正常工作

无法加载驱动程序类:在 Spring Boot 应用程序中的 org.h2.Driver