溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringCloud Gateway自帶的全局過濾器GlobalFilter是怎樣的

發(fā)布時(shí)間:2021-09-29 14:04:16 來源:億速云 閱讀:709 作者:柒染 欄目:編程語(yǔ)言

Gateway的全局過濾器GlobalFilter是怎樣的,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

全局過濾器作用于所有的路由,不需要單獨(dú)配置,我們可以用它來實(shí)現(xiàn)很多統(tǒng)一化處理的業(yè)務(wù)需求,比如權(quán)限認(rèn)證、IP 訪問限制等。

接口定義類 org.springframework.cloud.gateway.filter.GlobalFilter,具體代碼如下所示。

public interface GlobalFilter {Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

SpringCloud Gateway 自帶的 GlobalFilter 實(shí)現(xiàn)類有很多,如圖 1 所示。

SpringCloud Gateway自帶的全局過濾器GlobalFilter是怎樣的

有轉(zhuǎn)發(fā)、路由、負(fù)載等相關(guān)的 GlobalFilter,感興趣的朋友可以去看下源碼自行了解。我們?nèi)绾瓮ㄟ^定義 GlobalFilter 來實(shí)現(xiàn)我們的業(yè)務(wù)邏輯?

這里給出一個(gè)官方文檔上的案例,代碼如下所示。

@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 個(gè) GlobalFilter,通過 @Order 來指定執(zhí)行的順序,數(shù)字越小,優(yōu)先級(jí)越高。下面就是輸出的日志,從日志就可以看出執(zhí)行的順序,如下所示。

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

當(dāng) GlobalFilter 的邏輯比較多時(shí),筆者還是推薦大家單獨(dú)寫一個(gè) GlobalFilter 來處理,比如我們要實(shí)現(xiàn)對(duì) IP 的訪問限制,即不在 IP 白名單中就不能調(diào)用的需求。

單獨(dú)定義只需要實(shí)現(xiàn) GlobalFilter、Ordered 兩個(gè)接口就可以了,具體代碼如下所示。

@Componentpublic class IPCheckFilter implements GlobalFilter, Ordered {@Overridepublic int getOrder() {return 0;
    }@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        HttpHeaders headers = exchange.getRequest().getHeaders();// 此處寫得非常絕對(duì), 只作演示用, 實(shí)際中需要采取配置的方式if (getIp(headers).equals("127.0.0.1")) {
            ServerHttpResponse response = exchange.getResponse();
            ResponseData data = new ResponseData();data.setCode(401);data.setMessage("非法請(qǐng)求");
            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);
    }// 這里從請(qǐng)求頭中獲取用戶的實(shí)際IP,根據(jù)Nginx轉(zhuǎn)發(fā)的請(qǐng)求頭獲取private String getIp(HttpHeaders headers) {return "127.0.0.1";
    }
}

過濾的使用雖然比較簡(jiǎn)單,但作用很大,可以處理很多需求,上面講的 IP 認(rèn)證攔截只是冰山一角,更多的功能需要我們自己基于過濾器去實(shí)現(xiàn)。

看完上述內(nèi)容,你們掌握Gateway的全局過濾器GlobalFilter是怎樣的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI