【SpringCloud】Gateway自定义路由断言工厂

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

原文地址:https://www.cnblogs.com/h--d/p/15015746.html