我們來設定一個場景:假設我們的應用僅僅讓age在(min, max)之間的人來訪問。
第一步:在配置文件中,添加一個Age的斷言配置
1 # 端口 2 server: 3 port: 9527 4 5 spring: 6 application: 7 name: cloud-gateway-gateway 8 cloud: 9 gateway: 10 discovery: 11 locator: 12 # 開啟從注冊中心動態創建路由的功能,利用微服務名進行路由 13 enabled: true 14 # 忽略大小寫匹配,默認為 false。 15 # 當 eureka 自動大寫 serviceId 時很有用。 所以 MYSERIVCE,會匹配 /myservice/** 16 lowerCaseServiceId: true 17 routes: 18 # 路由id 19 - id: payment_routh 20 # 匹配后提供服務路由地址 21 uri: lb://cloud-payment-service 22 # 斷言 23 predicates: 24 # curl http://localhost:9527/payment/get/1 25 - Path=/payment/get/** 26 27 # 自定義Age斷言工廠 28 # Age:自動找到 "Age" + "RoutePredicateFactory" 斷言工廠 29 # 18,60: 斷言工廠參數 30 # 限制年齡[18, 60)的人能訪問 31 - Age=18,60 32 33 34 eureka: 35 client: 36 register-with-eureka: true 37 fetch-registry: true 38 service-url: 39 defaultZone: http://localhost:8761/eureka
第二步:自定義一個斷言工廠,實現斷言方法
1 package com.test.springcloud.predicate; 2 3 import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; 4 import org.springframework.stereotype.Component; 5 import org.springframework.util.MultiValueMap; 6 import org.springframework.util.StringUtils; 7 import org.springframework.validation.annotation.Validated; 8 import org.springframework.web.server.ServerWebExchange; 9 10 import java.util.Arrays; 11 import java.util.List; 12 import java.util.function.Consumer; 13 import java.util.function.Predicate; 14 15 // 自定義路由斷言工廠 16 @Component 17 public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> { 18 19 20 public AgeRoutePredicateFactory() { 21 super(AgeRoutePredicateFactory.Config.class); 22 } 23 24 // 將配置文件中的值按返回集合的順序,賦值給配置類 25 @Override 26 public List<String> shortcutFieldOrder() { 27 return Arrays.asList(new String[]{"minAge", "maxAge"}); 28 } 29 30 @Override 31 public Predicate<ServerWebExchange> apply(Consumer<Config> consumer) { 32 return super.apply(consumer); 33 } 34 35 @Override 36 public Predicate<ServerWebExchange> apply(Config config) { 37 // 創建網關斷言對象 38 return new Predicate<ServerWebExchange>() { 39 // 檢查 40 @Override 41 public boolean test(ServerWebExchange serverWebExchange) { 42 // TODO 獲取請求參數age,判斷是否滿足[18, 60) 43 MultiValueMap<String, String> queryParams = serverWebExchange.getRequest().getQueryParams(); 44 String age = queryParams.getFirst("age"); 45 if (!StringUtils.isEmpty(age) && age.matches("[0-9]+")) { 46 int iAge = Integer.parseInt(age); 47 if (iAge >= config.minAge && iAge < config.maxAge) { 48 return true; 49 } 50 } 51 return false; 52 } 53 }; 54 } 55 56 57 // 配置類,屬性用於接收配置文件中的值 58 @Validated 59 public static class Config { 60 private int minAge; 61 private int maxAge; 62 63 public int getMinAge() { 64 return minAge; 65 } 66 67 public void setMinAge(int minAge) { 68 this.minAge = minAge; 69 } 70 71 public int getMaxAge() { 72 return maxAge; 73 } 74 75 public void setMaxAge(int maxAge) { 76 this.maxAge = maxAge; 77 } 78 } 79 }
第三步:啟動測試
參考:https://www.freesion.com/article/36441306839/