javascript
Spring Cloud Alibaba - 25 Gateway-路由断言工厂Route Predicate Factories谓词工厂示例及源码解析
文章目錄
- 官網(wǎng)
- The After Route Predicate Factory
- 小栗子
- AfterRoutePredicateFactory源碼
- The Before Route Predicate Factory
- 小栗子
- BeforeRoutePredicateFactory源碼
- The Between Route Predicate Factory
- 小栗子
- BetweenRoutePredicateFactory源碼
- The Cookie Route Predicate Factory
- 小栗子
- CookieRoutePredicateFactory源碼
- The Header Route Predicate Factory
- 小栗子
- HeaderRoutePredicateFactory源碼
- The Host Route Predicate Factory
- The Method Route Predicate Factory
- The Path Route Predicate Factory
- The Query Route Predicate Factory
- The RemoteAddr Route Predicate Factory
- The Weight Route Predicate Factory
- 源碼
官網(wǎng)
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
Spring Cloud Gateway 將路由匹配為 Spring WebFluxHandlerMapping基礎(chǔ)架構(gòu)的一部分。Spring Cloud Gateway 包含許多內(nèi)置的路由謂詞工廠(chǎng)。所有這些謂詞都匹配 HTTP 請(qǐng)求的不同屬性。我們可以將多個(gè)路由謂詞工廠(chǎng)與邏輯and語(yǔ)句結(jié)合起來(lái)。
The After Route Predicate Factory
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-after-route-predicate-factory
小栗子
我們還是繼續(xù)老工程 ,啟動(dòng)
artisan-cloud-gateway 【8888】
artisan-cloud-gateway-order
artisan-cloud-gateway-product
【網(wǎng)關(guān)配置】
application-after_route.yml
# 網(wǎng)關(guān)的After謂詞,對(duì)應(yīng)的源碼處理AfterRoutePredicateFactory #作用: 經(jīng)過(guò)網(wǎng)關(guān)的所有請(qǐng)求 當(dāng)前時(shí)間>比After閾值 就進(jìn)行轉(zhuǎn)發(fā) #現(xiàn)在我們是2022年了 currentTime<After閾值,所以網(wǎng)關(guān)不會(huì)進(jìn)行轉(zhuǎn)發(fā),而返回404spring: spring:cloud:gateway: #gatewayroutes:- id: after_route # id 確保唯一uri: lb://artisan-cloud-gateway-order # nacos上的 注冊(cè)地址predicates:- After=2025-02-13T18:27:28.309+08:00[Asia/Shanghai]currentTime<After閾值,所以網(wǎng)關(guān)不會(huì)進(jìn)行轉(zhuǎn)發(fā) .
激活配置文件
【測(cè)試】
符合預(yù)期。
如果我們改下時(shí)間呢?
AfterRoutePredicateFactory源碼
public class AfterRoutePredicateFactoryextends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {/*** DateTime key.*/public static final String DATETIME_KEY = "datetime";public AfterRoutePredicateFactory() {super(Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList(DATETIME_KEY);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {final ZonedDateTime now = ZonedDateTime.now();return now.isAfter(config.getDatetime());}@Overridepublic String toString() {return String.format("After: %s", config.getDatetime());}};}public static class Config {@NotNullprivate ZonedDateTime datetime;public ZonedDateTime getDatetime() {return datetime;}public void setDatetime(ZonedDateTime datetime) {this.datetime = datetime;}}}核心方法,apply,比較簡(jiǎn)單。
The Before Route Predicate Factory
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-before-route-predicate-factory
小栗子
application-before_route.yml
#目的:測(cè)試網(wǎng)關(guān)的Before謂詞,對(duì)應(yīng)的源碼處理BeforeRoutePredicateFactory #作用: 經(jīng)過(guò)網(wǎng)關(guān)的所有請(qǐng)求當(dāng)前時(shí)間 比Before=2021-02-13T18:27:28.309+08:00[Asia/Shanghai] 小 就進(jìn)行轉(zhuǎn)發(fā) #現(xiàn)在2022年了 時(shí)間比配置的閾值大,所以我們不會(huì)進(jìn)行轉(zhuǎn)發(fā),而返回404 #2021-02-13T18:27:28.309+08:00[Asia/Shanghai] 這個(gè)時(shí)間怎么獲取的呢? --- System.out.println(ZonedDateTime.now()) spring:cloud:gateway: #gatewayroutes:- id: before_route # id 確保唯一uri: lb://artisan-cloud-gateway-orderpredicates:- Before=2023-02-13T18:27:28.309+08:00[Asia/Shanghai]BeforeRoutePredicateFactory源碼
public class BeforeRoutePredicateFactoryextends AbstractRoutePredicateFactory<BeforeRoutePredicateFactory.Config> {/*** DateTime key.*/public static final String DATETIME_KEY = "datetime";public BeforeRoutePredicateFactory() {super(Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList(DATETIME_KEY);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {final ZonedDateTime now = ZonedDateTime.now();return now.isBefore(config.getDatetime());}@Overridepublic String toString() {return String.format("Before: %s", config.getDatetime());}};}public static class Config {private ZonedDateTime datetime;public ZonedDateTime getDatetime() {return datetime;}public void setDatetime(ZonedDateTime datetime) {this.datetime = datetime;}}}The Between Route Predicate Factory
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-between-route-predicate-factory
小栗子
application-between-route.yml
# Between謂詞 BetweenRoutePredicateFactory # 就是經(jīng)過(guò)網(wǎng)關(guān)請(qǐng)求的當(dāng)前時(shí)間 currentTime 滿(mǎn)足 # Between startTime < currentTime < Between EndTime 才進(jìn)行轉(zhuǎn)發(fā) spring:cloud:gateway:routes:- id: between-route #id必須要唯一uri: lb://artisan-cloud-gateway-order # 這里可以使用負(fù)載均衡的寫(xiě)法predicates:- Between=2020-02-13T18:27:28.309+08:00[Asia/Shanghai],2025-02-13T18:27:28.309+08:00[Asia/Shanghai]BetweenRoutePredicateFactory源碼
public class BetweenRoutePredicateFactoryextends AbstractRoutePredicateFactory<BetweenRoutePredicateFactory.Config> {/*** DateTime 1 key.*/public static final String DATETIME1_KEY = "datetime1";/*** DateTime 2 key.*/public static final String DATETIME2_KEY = "datetime2";public BetweenRoutePredicateFactory() {super(Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList(DATETIME1_KEY, DATETIME2_KEY);}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {Assert.isTrue(config.getDatetime1().isBefore(config.getDatetime2()),config.getDatetime1() + " must be before " + config.getDatetime2());return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {final ZonedDateTime now = ZonedDateTime.now();return now.isAfter(config.getDatetime1())&& now.isBefore(config.getDatetime2());}@Overridepublic String toString() {return String.format("Between: %s and %s", config.getDatetime1(),config.getDatetime2());}};}@Validatedpublic static class Config {@NotNullprivate ZonedDateTime datetime1;@NotNullprivate ZonedDateTime datetime2;public ZonedDateTime getDatetime1() {return datetime1;}public Config setDatetime1(ZonedDateTime datetime1) {this.datetime1 = datetime1;return this;}public ZonedDateTime getDatetime2() {return datetime2;}public Config setDatetime2(ZonedDateTime datetime2) {this.datetime2 = datetime2;return this;}}}The Cookie Route Predicate Factory
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-cookie-route-predicate-factory
小栗子
application-cookie-route.yml
#謂詞 Cookie 源碼 CookieRoutePredicateFactory #表示通過(guò)網(wǎng)關(guān)的請(qǐng)求 必須帶入包含了Cookie name=Company value=Artisan #才轉(zhuǎn)發(fā)請(qǐng)求 spring:cloud:gateway:routes:- id: cookie-route #id必須要唯一uri: lb://artisan-cloud-gateway-order # 這里可以使用負(fù)載均衡的寫(xiě)法predicates:#當(dāng)我們的請(qǐng)求中包含了Cookie name=Company value=Artisan#才轉(zhuǎn)發(fā)請(qǐng)求- Cookie=Company,ArtisanCookieRoutePredicateFactory源碼
核心方法
@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange exchange) {List<HttpCookie> cookies = exchange.getRequest().getCookies().get(config.name);if (cookies == null) {return false;}for (HttpCookie cookie : cookies) {if (cookie.getValue().matches(config.regexp)) {return true;}}return false;}@Overridepublic String toString() {return String.format("Cookie: name=%s regexp=%s", config.name,config.regexp);}};}The Header Route Predicate Factory
https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-header-route-predicate-factory
小栗子
application-header-route.yml
#Header謂詞 源碼HeaderRoutePredicateFactory #說(shuō)明請(qǐng)求經(jīng)過(guò)網(wǎng)關(guān) 必須帶入 #header的k=X-Request-appId v=Artisan才會(huì)被轉(zhuǎn)發(fā) spring:cloud:gateway:routes:- id: header-route #id必須要唯一uri: lb://artisan-cloud-gateway-orderpredicates:- Header=X-Request-appId,ArtisanHeaderRoutePredicateFactory源碼
@Overridepublic Predicate<ServerWebExchange> apply(Config config) {boolean hasRegex = !StringUtils.isEmpty(config.regexp);return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange exchange) {List<String> values = exchange.getRequest().getHeaders().getOrDefault(config.header, Collections.emptyList());if (values.isEmpty()) {return false;}// values is now guaranteed to not be emptyif (hasRegex) {// check if a header value matchesreturn values.stream().anyMatch(value -> value.matches(config.regexp));}// there is a value and since regexp is empty, we only check existence.return true;}@Overridepublic String toString() {return String.format("Header: %s regexp=%s", config.header,config.regexp);}};}The Host Route Predicate Factory
#Host謂詞 源碼HostRoutePredicateFactory #說(shuō)明請(qǐng)求http://localhost:8888/selectOrderInfoById/1的 #Host必須滿(mǎn)足www.artisan.com:8888或者localhost:8888才會(huì) #轉(zhuǎn)發(fā)到http://artisan-cloud-gateway-order/selectOrderInfoById/1#而127.0.0.1不會(huì)被轉(zhuǎn)發(fā) spring:cloud:gateway:routes:- id: host-route #id必須要唯一uri: lb://artisan-cloud-gateway-orderpredicates:- Host=www.artisan.com:8888,localhost:8888The Method Route Predicate Factory
#Http請(qǐng)求方法的謂詞 Method 源碼 MethodRoutePredicateFactory #表示經(jīng)過(guò)網(wǎng)關(guān)的請(qǐng)求 只有post方式才能被轉(zhuǎn)發(fā) spring:cloud:gateway:routes:- id: method #id必須要唯一uri: lb://artisan-cloud-gateway-orderpredicates:#當(dāng)前請(qǐng)求的方式 http://localhost:8888/selectOrderInfoById/1 是Post才會(huì)被轉(zhuǎn)發(fā)#到http://artisan-cloud-gateway-order/selectOrderInfoById/1- Method=PostThe Path Route Predicate Factory
The Query Route Predicate Factory
The RemoteAddr Route Predicate Factory
The Weight Route Predicate Factory
源碼
https://github.com/yangshangwei/SpringCloudAlibabMaster
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud Alibaba - 25 Gateway-路由断言工厂Route Predicate Factories谓词工厂示例及源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring Cloud Alibaba
- 下一篇: Spring Cloud Alibaba