报错信息

如果是动态刷新路由报如下错误的话:

reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under '' to org.springframework.cloud.gateway.handler.predicate.QueryRoutePredicateFactory$Config
Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under '' to org.springframework.cloud.gateway.handler.predicate.QueryRoutePredicateFactory$Config
	at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:363) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:323) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:308) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.bindOrCreate(Binder.java:300) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.bindOrCreate(Binder.java:285) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.cloud.gateway.support.ConfigurationService.bindOrCreate(ConfigurationService.java:139) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.support.ConfigurationService$ConfigurableBuilder.doBind(ConfigurationService.java:188) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.support.ConfigurationService$AbstractBuilder.bind(ConfigurationService.java:286) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.lookup(RouteDefinitionRouteLocator.java:281) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.combinePredicates(RouteDefinitionRouteLocator.java:248) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.convertToRoute(RouteDefinitionRouteLocator.java:169) ~[spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmitScalar(FluxFlatMap.java:480) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:413) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.drain(FluxMergeSequential.java:425) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.innerComplete(FluxMergeSequential.java:321) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialInner.onSubscribe(FluxMergeSequential.java:544) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:161) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Flux.subscribe(Flux.java:8357) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.onNext(FluxMergeSequential.java:230) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:267) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:225) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.onSubscribe(FluxMergeSequential.java:191) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:161) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Flux.subscribe(Flux.java:8357) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.onNext(FluxMergeSequential.java:230) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:267) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:225) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxMergeSequential$MergeSequentialMain.onSubscribe(FluxMergeSequential.java:191) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:161) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4252) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4363) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4223) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4159) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4106) ~[reactor-core-3.3.12.RELEASE.jar:3.3.12.RELEASE]
	at org.springframework.cloud.gateway.route.CachingRouteLocator.onApplicationEvent(CachingRouteLocator.java:82) [spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.CachingRouteLocator.onApplicationEvent(CachingRouteLocator.java:40) [spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.cloud.gateway.route.RouteRefreshListener.reset(RouteRefreshListener.java:75) [spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.RouteRefreshListener.resetIfNeeded(RouteRefreshListener.java:70) [spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.cloud.gateway.route.RouteRefreshListener.onApplicationEvent(RouteRefreshListener.java:64) [spring-cloud-gateway-server-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) [spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at com.alibaba.cloud.nacos.discovery.NacosWatch$1.onEvent(NacosWatch.java:100) [spring-cloud-starter-alibaba-nacos-discovery-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at com.alibaba.nacos.client.naming.core.EventDispatcher$Notifier.run(EventDispatcher.java:177) [nacos-client-1.3.2.jar:na]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
Caused by: org.springframework.boot.context.properties.bind.validation.BindValidationException: Binding validation errors on 
   - Field error in object '' on field 'param': rejected value [null]; codes [NotEmpty.param,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [.param,param]; arguments []; default message [param]]; default message [不能为空]
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validateAndPush(ValidationBindHandler.java:139) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validate(ValidationBindHandler.java:112) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.onFinish(ValidationBindHandler.java:103) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.handleBindResult(Binder.java:339) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:320) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	... 56 common frames omitted

解决办法

原因

这里是因为PredicateDefinition在添对应的Predicate的时候,根据PredicateDefinition的name取出对应的XXXXRoutePredicateFactory。比如name是Query,那么对应的就是QueryRoutePredicateFactory,如果name是Header,那么对应的就是HeaderRoutePredicateFactory。取到对应的XXXXRoutePredicateFactory后,会用他们的内部类Config去解析PredicateDefinition.addArg的参数。这里的addArg会有一个key,这里的key必须和XXXXRoutePredicateFactory的对应。

错误示范
predicateDefinition.setName("Query");
predicateDefinition.addArg("query", "clientId, " + uploadClientId);

这里就会报上面的错误,因为在QueryRoutePredicateFactory配置了key的值

	/**
	 * Param key.
	 */
	public static final String PARAM_KEY = "param";

	/**
	 * Regexp key.
	 */
	public static final String REGEXP_KEY = "regexp";
正确示范
predicateDefinition.setName("Query");
predicateDefinition.addArg("param", "clientId");
predicateDefinition.addArg("regexp", "1");
解决办法

去对应的XXXXRoutePredicateFactory找到他们的key值。比如HeaderRoutePredicateFactory叫header;AfterRoutePredicateFactory的是datetime。其他可以自己查找。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐