H__D  

  我们来设定一个场景:假设我们的应用仅仅让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 
28           filters:
29             # 自定义Age过滤器工厂
30             # Age:自动找到 "Age" + "GatewayFilterFactory" 过滤器工厂
31             # 18,60: 断言工厂参数
32             # 限制年龄[18, 60)的人能访问
33             - name: Age
34               args:
35                 name: minAge,maxAge
36                 value: 18,60
37 
38 eureka:
39   client:
40     register-with-eureka: true
41     fetch-registry: true
42     service-url:
43       defaultZone: http://localhost:8761/eureka

第二步:自定义一个过滤器工厂,实现过滤方法

  自定义过滤器工厂 继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。

 1 package com.test.springcloud.filter;
 2 
 3 import org.springframework.cloud.gateway.filter.GatewayFilter;
 4 import org.springframework.cloud.gateway.filter.GatewayFilterChain;
 5 import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
 6 import org.springframework.core.io.buffer.DataBuffer;
 7 import org.springframework.http.server.reactive.ServerHttpResponse;
 8 import org.springframework.stereotype.Component;
 9 import org.springframework.util.MultiValueMap;
10 import org.springframework.util.StringUtils;
11 import org.springframework.web.server.ServerWebExchange;
12 import reactor.core.publisher.Mono;
13 
14 import java.nio.charset.StandardCharsets;
15 
16 // 继承AbstractNameValueGatewayFilterFactory且
17 // 我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。
18 // 自定义过滤器工厂
19 @Component
20 public class AgeGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
21     @Override
22     public GatewayFilter apply(NameValueConfig config) {
23         System.out.println("config.getName() = " + config.getName());
24         System.out.println("config.getValue() = " + config.getValue());
25 //        int minAge = Integer.parseInt(config.getName());
26 //        int maxAge = Integer.parseInt(config.getValue());
27         String[] arr = config.getValue().split(",");
28         int minAge = Integer.parseInt(arr[0]);
29         int maxAge = Integer.parseInt(arr[1]);
30         return new GatewayFilter() {
31             @Override
32             public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
33                 // TODO 获取请求参数age,判断是否满足[18, 60)
34                 MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
35                 String age = queryParams.getFirst("age");
36                 if (!StringUtils.isEmpty(age) && age.matches("[0-9]+")) {
37                     int iAge = Integer.parseInt(age);
38                     if (iAge >= minAge && iAge < maxAge) {
39                          return  chain.filter(exchange);
40                     }
41                 }
42 
43                 ServerHttpResponse response = exchange.getResponse();
44                 byte[] bits = "请求参数 age 不满足[18, 60)".getBytes(StandardCharsets.UTF_8);
45                 DataBuffer buffer = response.bufferFactory().wrap(bits);
46                 //指定编码,否则在浏览器中会中文乱码
47                 response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
48                 return response.writeWith(Mono.just(buffer));
49             }
50         };
51     }
52 }

第三步:启动测试

   

 

posted on 2021-07-15 16:25  H__D  阅读(719)  评论(0编辑  收藏  举报