1. 程式人生 > 程式設計 >Spring Boot專案中如何定製攔截器

Spring Boot專案中如何定製攔截器

本文首發於個人網站:Spring Boot專案中如何定製攔截器

Servlet 過濾器屬於Servlet API,和Spring關係不大。除了使用過濾器包裝web請求,Spring MVC還提供HandlerInterceptor(攔截器)工具。根據檔案,HandlerInterceptor的功能跟過濾器類似,但攔截器提供更精細的控制能力:在request被響應之前、request被響應之後、檢視渲染之前以及request全部結束之後。我們不能通過攔截器修改request內容,但是可以通過丟擲異常(或者返回false)來暫停request的執行。

Spring MVC中常用的攔截器有:LocaleChangeInterceptor(用於國際化配置)

ThemeChangeInterceptor。我們也可以增加自己定義的攔截器,可以參考這篇文章中提供的demo

實戰

新增攔截器不僅是在WebConfiguration中定義bean,Spring Boot提供了基礎類WebMvcConfigurerAdapter,我們專案中的WebConfiguration類需要繼承這個類。

  1. 繼承WebMvcConfigurerAdapter;
  2. 為LocaleChangeInterceptor新增@Bean定義,這僅僅是定義了一個interceptor spring bean,但是Spring boot不會自動將它加入到呼叫鏈中。
  3. 攔截器需要手動加入呼叫鏈。

修改後完整的WebConfiguration程式碼如下:

package com.test.bookpub;

import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
    @Bean    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean    public LocaleChangeInterceptor localeChangeInterceptor() {
        return new LocaleChangeInterceptor();
    }
    @Override    public void addInterceptors(InterceptorRegistry registry {
        registry.addInterceptor(localeChangeInterceptor());
    }
}複製程式碼

使用mvn spring-boot:run執行程式,然後通過httpie訪問http://localhost:8080/books?locale=foo,在終端看到如下錯誤資訊。

Servlet.service() for servlet [dispatcherServlet] in context with path [] 
threw exception [Request processing failed; nested exception is 
java.lang.UnsupportedOperationException: Cannot change HTTP accept 
header - use a different locale resolution strategy] with root cause複製程式碼

PS:這裡發生錯誤並不是因為我們輸入的locale是錯誤的,而是因為預設的locale修改策略不允許來自瀏覽器的請求修改。發生這樣的錯誤說明我們之前定義的攔截器起作用了。

分析

在我們的示例專案中,覆蓋並重寫了addInterceptors(InterceptorRegistory registory)方法,這是典型的回撥函式——利用該函式的引數registry來新增自定義的攔截器。

在Spring Boot的自動配置階段,Spring Boot會掃描所有WebMvcConfigurer的例項,並順序呼叫其中的回撥函式,這表示:如果我們想對配置資訊做邏輯上的隔離,可以在Spring Boot專案中定義多個WebMvcConfigurer的例項。

Spring Boot 1.x系列

  1. Spring Boot的自動配置、Command-line-Runner
  2. 瞭解Spring Boot的自動配置
  3. Spring Boot的@PropertySource註解在整合Redis中的使用
  4. Spring Boot專案中如何定製HTTP訊息轉換器
  5. Spring Boot整合Mongodb提供Restful介面
  6. Spring中bean的scope
  7. Spring Boot專案中使用事件派發器模式
  8. Spring Boot提供RESTful介面時的錯誤處理實踐
  9. Spring Boot實戰之定製自己的starter
  10. Spring Boot專案如何同時支援HTTP和HTTPS協議
  11. 自定義的Spring Boot starter如何設定自動配置註解
  12. Spring Boot專案中使用Mockito
  13. 在Spring Boot專案中使用Spock測試框架

***本號專注於後端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這裡有所收穫。javaadu