您好,登錄后才能下訂單哦!
Gateway的全局過濾器GlobalFilter是怎樣的,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
全局過濾器作用于所有的路由,不需要單獨配置,我們可以用它來實現很多統一化處理的業務需求,比如權限認證、IP 訪問限制等。
接口定義類 org.springframework.cloud.gateway.filter.GlobalFilter,具體代碼如下所示。
public interface GlobalFilter {Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }
SpringCloud Gateway 自帶的 GlobalFilter 實現類有很多,如圖 1 所示。
有轉發、路由、負載等相關的 GlobalFilter,感興趣的朋友可以去看下源碼自行了解。我們如何通過定義 GlobalFilter 來實現我們的業務邏輯?
這里給出一個官方文檔上的案例,代碼如下所示。
@Configurationpublic class ExampleConfiguration {private Logger log = LoggerFactory.getLogger(ExampleConfiguration.class);@Bean@Order(-1)public GlobalFilter a() {return (exchange, chain) -> { log.info("first pre filter");return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("third post filter"); })); }; }@Bean@Order(0)public GlobalFilter b() {return (exchange, chain) -> { log.info("second pre filter");return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("second post filter"); })); }; }@Bean@Order(1)public GlobalFilter c() {return (exchange, chain) -> { log.info("third pre filter");return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("first post filter"); })); }; } }
上面定義了 3 個 GlobalFilter,通過 @Order 來指定執行的順序,數字越小,優先級越高。下面就是輸出的日志,從日志就可以看出執行的順序,如下所示。
2019-8-26 16:08:52.406 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : first pre filter2019-8-26 16:08:52.406 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : second pre filter2019-8-26 16:08:52.407 INFO 55062 --- [ioEventLoop-4-1] c.c.gateway.config.ExampleConfiguration : third pre filter2019-8-26 16:08:52.437 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : first post filter2019-8-26 16:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : second post filter2019-8-26 16:08:52.438 INFO 55062 --- [ctor-http-nio-7] c.c.gateway.config.ExampleConfiguration : third post filter
當 GlobalFilter 的邏輯比較多時,筆者還是推薦大家單獨寫一個 GlobalFilter 來處理,比如我們要實現對 IP 的訪問限制,即不在 IP 白名單中就不能調用的需求。
單獨定義只需要實現 GlobalFilter、Ordered 兩個接口就可以了,具體代碼如下所示。
@Componentpublic class IPCheckFilter implements GlobalFilter, Ordered {@Overridepublic int getOrder() {return 0; }@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { HttpHeaders headers = exchange.getRequest().getHeaders();// 此處寫得非常絕對, 只作演示用, 實際中需要采取配置的方式if (getIp(headers).equals("127.0.0.1")) { ServerHttpResponse response = exchange.getResponse(); ResponseData data = new ResponseData();data.setCode(401);data.setMessage("非法請求"); byte[] datas = JsonUtils.toJson(data).getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(datas); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");return response.writeWith(Mono.just(buffer)); }return chain.filter(exchange); }// 這里從請求頭中獲取用戶的實際IP,根據Nginx轉發的請求頭獲取private String getIp(HttpHeaders headers) {return "127.0.0.1"; } }
過濾的使用雖然比較簡單,但作用很大,可以處理很多需求,上面講的 IP 認證攔截只是冰山一角,更多的功能需要我們自己基于過濾器去實現。
看完上述內容,你們掌握Gateway的全局過濾器GlobalFilter是怎樣的的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。