我们来设定一个场景:假设我们的应用仅仅让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 }
第三步:启动测试