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 就可以了。如下:
非常簡單不是嗎?但是這種方式無法保證順序,而且作用於所有的請求,即攔截的 Ant 規則為 /*。所以需要我們改進
2.2 實現 Filter 順序化
如果需要實現順序化,可以藉助於 Spring 提供的 @Order 註解或者 Ordered 接口。這裡有一個坑:如果使用 @Order 註解一定要註解標註到具體的類上。 為了方便 JavaConfig 風格的聲明。我們可以實現 OrderedFilter 接口,該接口是 Filter接口和 Ordered 接口的複合體,最終上面的配置如下
Filter 執行的規則是 數字越小越先執行 。跟之前 Bean 實例化的優先級是一致的。
2.3 自定義 Filter 作用域
實現了順序化之後我們來看看如何實現自定義 Filter 的作用域。我們先說一下思路:
通過 ServletRequest 對象來獲取請求的 URI,然後對 URI 進行 ANT 風格匹配, 匹配通過執行具體的邏輯,否則跳過該 Filter 。
這裡非常適合抽象一個基類來把該流程固定下來,留一個抽象方法作為函數鉤子,只需要繼承基類實現該抽象方法鉤子就可以了。 為了保證順序執行基類我們依然實現了 OrderedFilter 接口,我們來定義基類:
我們來實現一個具體的 Filter 邏輯,打印請求的 URI:
然後定義好其 urlPatterns 並將其註冊到 Spring IoC 容器中就行了,如果有多個而且希望按照一定的順序執行。
3. Spring Boot的機制
以上方式是我們自己造的輪子。其實 Spring Boot 還提供了 Filter 註冊機制來實現順序執行和聲明作用域。 我們上面的邏輯可以改為:
3.1 要點
- FilterRegistrationBean 與 Filter 之間是一對一關係。
- 如果存在多個 FilterRegistrationBean 需要調用其 setName(String name) 為其聲明唯一名稱,否則只有第一個註冊成功的有效。
- 如果需要保證調用順序可通過調用其 setOrder(int order) 方法進行設置。
4. 總結
我們在本文中通過自定義和 Spring Boot 提供的兩種方式實現了使用自定義 Filter ,雖然 Spring Boot 提供的方式更加方便一些,但是自定義的方式更能體現你對面向對象理解和提高你的抽象能力。希望多多關注,與往常一樣。
閱讀更多 小哇說互聯 的文章