Spring Boot 攔截器無效,不起作用

這個問題一般是解決WebMvcConfigurerAdapter過時問題造成的。導致這個問題可能有兩個原因:一個是攔截器寫錯了,另一個是攔截器配置錯了。

1、需求是這樣的

攔截所有的api請求,判斷其請求頭中的secret參數是否正確,正確的請求才能訪問api

2、攔截器配置

需要先寫攔截器,然後再配置到Spring Boot環境中。

2.1、寫一個攔截器

Spring MVC中,攔截器有兩種寫法:要麼實現HandlerInterceptor接口,要麼實現WebRequestInterceptor接口,具體內容請看這裏詳述 Spring MVC 框架中攔截器 Interceptor 的使用方法
Spring Boot也只是集成了Spring MVC而已,所以攔截器的寫法還是一樣的。不一樣的是Spring MVC的攔截器需要在xml文件中配置,而Spring Boot只需要在類上加@Component註解即可,這樣當前攔截器纔會被掃描到。
這裏只需要實現HandlerInterceptor接口即可(這裏沒啥坑)。

@Component
public class SecurityInterceptor implements HandlerInterceptor {
   private static final Logger LOGGER = LoggerFactory.getLogger(SecurityInterceptor.class);

   private final ApiSecurityProperties security;

   @Autowired
   public SecurityInterceptor(ApiSecurityProperties security) {
       this.security = security;
   }

   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       String url = request.getRequestURI();
       if (!url.contains"/api")) {
           return true;
       }
       String secret = request.getHeader("secret");
       if (!security.getSecret().equals(secret)) {
           // 祕鑰不匹配
           response.setCharacterEncoding("UTF-8");
           response.setContentType("application/json; charset=utf-8");
           Res<Void> res = ResUtils.error("The argument 'secret' in request headers is error, please check it again.");
           String result = new Gson().toJson(res);
           PrintWriter out = response.getWriter();
           out.print(result);
           out.close();
           return false;
       }
       return true;
   }
}

2.2、將攔截器配置到Spring Boot環境中

目前(2.0.4.RELEASE版本)WebMvcConfigurerAdapter已過時,如果你執意要用的話,應該沒啥坑。但是被強迫症時刻針對的人,坑就來啦。
WebMvcConfigurerAdapter過時了,那麼用誰來代替呢?機智的人可能早就發現了,過時的這個只不過是個適配器(適配器模式),那就可以直接使用它所實現的那個接口啊,就是WebMvcConfigurer唄。對,就是這個,別猶豫了。。我就被百度坑得不輕,具體說說怎麼被坑的吧。


  • 百度後我查到的解決方案這樣的

兩種方法,並且都還強烈推薦第二種方法
// 方法一:實現WebMvcConfigurer接口
public class WebConfig implements WebMvcConfigurer{
    // ...
}

// 方法二:繼承WebMvcConfigurationSupport類
public class WebConfig extends WebMvcConfigurationSupport{
    // ...
}

於是就直接用了第二種方法,寫完跑了項目發現沒啥效果,打日誌也出不來。然後又改回第一種方法,果然,有效果了。

具體配置如下
必須加上@Configuration註解,這樣裏邊的@Bean才能起作用,Spring才能統一管理當前的攔截器實例。
addPathPatterns("/api/**")配置攔截路徑,其中/**表示當前目錄以及所有子目錄(遞歸),/*表示當前目錄,不包括子目錄。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final ApiSecurityProperties security;

    @Autowired
    public WebMvcConfig(ApiSecurityProperties security) {
        this.security = security;
    }

    @Bean
    public SecurityInterceptor securityInterceptor() {
        return new SecurityInterceptor(security);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加攔截器
        registry.addInterceptor(securityInterceptor()).addPathPatterns("/api/**");
    }
}

不出意外的話,你的攔截器應該起作用啦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章