01.02 Spring Boot 實戰:如何自定義 Servlet Filter

1.前言

有些時候我們需要在

Spring Boot Servlet Web 應用中聲明一些自定義的 Servlet Filter 來處理一些邏輯。比如簡單的權限系統、請求頭過濾、防止 XSS 攻擊等。本篇將講解如何在 Spring Boot 應用中聲明自定義 Servlet Filter 以及定義它們各自的作用域和順序。

2. 自定義 Filter

可能有人說聲明 Servlet Filter 不就是實現 Filter 接口嘛,沒有什麼好講的!是的這個沒錯,但是很多時候我們並不想我們聲明的 Filter 作用於全部的請求。甚至當一個請求經過多個 Filter 時需要按照既定的順序執行。接下來我會一一講解如何實現以上的功能。

在 Spring Boot 中 只需要聲明一個實現 javax.servlet.Filter 接口的 Spring Bean 就可以了。如下:

Spring Boot  實戰:如何自定義 Servlet Filter

非常簡單不是嗎?但是這種方式無法保證順序,而且作用於所有的請求,即攔截的 Ant 規則為 /*。所以需要我們改進

2.2 實現 Filter 順序化

如果需要實現順序化,可以藉助於 Spring 提供的 @Order 註解或者 Ordered 接口。這裡有一個坑:如果使用 @Order 註解一定要註解標註到具體的類上。 為了方便 JavaConfig 風格的聲明。我們可以實現 OrderedFilter 接口,該接口是 Filter接口和 Ordered 接口的複合體,最終上面的配置如下

Spring Boot  實戰:如何自定義 Servlet Filter


Filter 執行的規則是 數字越小越先執行 。跟之前 Bean 實例化的優先級是一致的。

2.3 自定義 Filter 作用域

實現了順序化之後我們來看看如何實現自定義 Filter 的作用域。我們先說一下思路:

通過 ServletRequest 對象來獲取請求的 URI,然後對 URI 進行 ANT 風格匹配, 匹配通過執行具體的邏輯,否則跳過該 Filter

這裡非常適合抽象一個基類來把該流程固定下來,留一個抽象方法作為函數鉤子,只需要繼承基類實現該抽象方法鉤子就可以了。 為了保證順序執行基類我們依然實現了 OrderedFilter 接口,我們來定義基類:

Spring Boot  實戰:如何自定義 Servlet Filter


Spring Boot  實戰:如何自定義 Servlet Filter

我們來實現一個具體的 Filter 邏輯,打印請求的 URI

Spring Boot  實戰:如何自定義 Servlet Filter

然後定義好其 urlPatterns 並將其註冊到 Spring IoC 容器中就行了,如果有多個而且希望按照一定的順序執行。

3. Spring Boot的機制

以上方式是我們自己造的輪子。其實 Spring Boot 還提供了 Filter 註冊機制來實現順序執行和聲明作用域。 我們上面的邏輯可以改為:

Spring Boot  實戰:如何自定義 Servlet Filter


Spring Boot  實戰:如何自定義 Servlet Filter

3.1 要點

  • FilterRegistrationBean 與 Filter 之間是一對一關係。
  • 如果存在多個 FilterRegistrationBean 需要調用其 setName(String name) 為其聲明唯一名稱,否則只有第一個註冊成功的有效。
  • 如果需要保證調用順序可通過調用其 setOrder(int order) 方法進行設置。

4. 總結

我們在本文中通過自定義和 Spring Boot 提供的兩種方式實現了使用自定義 Filter ,雖然 Spring Boot 提供的方式更加方便一些,但是自定義的方式更能體現你對面向對象理解和提高你的抽象能力。希望多多關注,與往常一樣。

Spring Boot  實戰:如何自定義 Servlet Filter


分享到:


相關文章: