当前位置: 代码迷 >> 综合 >> Spring Cloud Gateway之校验断言(Predicate)
  详细解决方案

Spring Cloud Gateway之校验断言(Predicate)

热度:61   发布时间:2024-02-02 00:59:38.0

文章目录

        • 1 介绍
        • 2 校验配置


1 介绍

spring cloud gateway源码中,内置了大量的Predicate工具,用于处理不同情况下的断言信息,
在这里插入图片描述
对于每一个断言参数的配置,可以参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories

2 校验配置

对于每一个 断言(Predicate),其配置的方式都有两种,
Shortcut Configuration,Fully Expanded Arguments
第一种方式,通过单一text配置

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- Cookie=mycookie,mycookievalue

gateway源码在实例化配置时,通过public PredicateDefinition(String text)构造函数去解析

public PredicateDefinition(String text) {int eqIdx = text.indexOf('=');if (eqIdx <= 0) {throw new ValidationException("Unable to parse PredicateDefinition text '"+ text + "'" + ", must be of the form name=value");}setName(text.substring(0, eqIdx));String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), ",");for (int i = 0; i < args.length; i++) {this.args.put(NameUtils.generateName(i), args[i]);}}

通过"="进行name,和args拆分,然后再通过:String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), “,”); 解析对应的args参数,
Fully Expanded Arguments即采用标准的yml格式进行配置:

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- name: Cookieargs:name: mycookieregexp: mycookievalue

gateway源码中,首先会去获取所有的RoutePredicateFactory类型的Predicates,

public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,List<GatewayFilterFactory> GatewayFilters,List<RoutePredicateFactory> predicates,RouteDefinitionLocator routeDefinitionLocator,@Qualifier("webFluxConversionService") ConversionService conversionService) {return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,GatewayFilters, properties, conversionService);}

然后实例化RouteLocator类型的RouteDefinitionRouteLocator

public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,List<RoutePredicateFactory> predicates,List<GatewayFilterFactory> gatewayFilterFactories,GatewayProperties gatewayProperties, ConversionService conversionService) {this.routeDefinitionLocator = routeDefinitionLocator;this.conversionService = conversionService;initFactories(predicates);gatewayFilterFactories.forEach(factory -> this.gatewayFilterFactories.put(factory.name(), factory));this.gatewayProperties = gatewayProperties;}

调用initFactories(predicates);方法,将内置的Predicate解析成对应的
Map<String, RoutePredicateFactory> predicates 类型,存放到RouteDefinitionRouteLocator 中的成员变量predicates中,
在这里,我们可以看到,gateway源码对应每一个Predicate的定时的key是通过,
NameUtils.normalizeRoutePredicateName(getClass());
进行解析获取

public static String normalizeRoutePredicateName(Class<? extends RoutePredicateFactory> clazz) {return removeGarbage(clazz.getSimpleName().replace(RoutePredicateFactory.class.getSimpleName(), ""));}

该方法实际上是通过替换,将每一个Predicate类的名称进行替换,例如:
HostRoutePredicateFactory 替换成Host(截取掉了RoutePredicateFactory.class.getSimpleName())信息

  相关解决方案