Skip to main content

升级spring-cloud-gateway到4.1.0的过程中遇到的问题的以及对应解决方案

· 2 min read
orange
programmer on jvm platform

此文记录了升级spring-cloud-gateway到4.1.0的过程中遇到的问题以及对应的解决方案.

spring.cloud.gateway.routes中定义的转发规则失效, 提示404 NOT_FOUND "No static resource xxx."

问题原因

这个问题的原因是项目中的类继承了org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping 但是新版本不兼容导致的.
在新版本中RoutePredicateHandlerMapping@Bean定义增加了@ConditionalOnMissingBean.

定义位于org.springframework.cloud.gateway.config.GatewayAutoConfiguration中.
RoutePredicateHandlerMappingHandlerMapping的实现, 对于注册到容器中的HandlerMapping, spring-mvc-reactive 会自动调用这些类的方法来尝试处理请求.

由于多出了@ConditionalOnMissingBean这会导致框架内置的和自定义的RoutePredicateHandlerMapping出现互斥的问题, 即只会被注册一次.

但是由于重写的方法只实现了部分自定义的转发规则, 从而导致spring.cloud.gateway.routes中定义的转发规则失效.

3.0.2中的Bean定义如下:


@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}

3.4.0中的Bean定义如下:


@Bean
@ConditionalOnMissingBean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}

解决方案

修改继承类重写的protected Mono<Route> lookupRoute(ServerWebExchange exchange)方法的实现, 先调用父类的方法, 如果父类方法返回为空, 则执行自定义的转发规则以确保spring.cloud.gateway.routes中定义的转发规则生效.


@Override
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return super.lookupRoute(exchange).switchIfEmpty(Mono.defer(() -> {
// 此处为自定义的转发规则
}
));
}