我们来设定一个场景:假设我们的应用仅仅让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/