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

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