大家都知道,spring-boot-stater-webspring-cloud-gateway不能同时引入,所以@RequestMapping等注解,都直接用的gateway包中的mvc模块带的,不过这时候:

application.yml添加的server.servlet.context-pathspring.mvc.servlet.path配置mvc前缀都会失效

那么我们想要使用gateway中的mvc,同时支持前缀,又想要使用网关,不影响网关的正常转发功能,那么我们可以采用以下思路:

1、通过gateway的webflux filter首先全局添加前缀

2、然后网关转发的过滤器中再移除前缀,避免影响网关的正常转发

经过以上操作,我们便可以mvc支持前缀,同时网关转发不受影响了

第一个全局过滤器:所有请求都会经过:



@Configuration
@Slf4j
public class GlobalMvcFilter {


    @Value("${spring.api.prefix}")
    private String apiPrefix;

    /**
     * 添加统一前缀,供mvc使用
     */
    @Bean
    @ConditionalOnProperty("spring.api.prefix")
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public WebFilter contextPathWebFilter() {
        return (exchange, chain) -> addApiPrefixFilter(exchange, chain);
    }

    private Mono<Void> addApiPrefixFilter(ServerWebExchange exchange, WebFilterChain chain) {
        //统一添加前缀,并且校验请求是否前缀开头
        ServerHttpRequest request = exchange.getRequest();
        String requestPath = request.getURI().getPath();
        if (requestPath.startsWith(apiPrefix)) {
            ServerHttpRequest newRequest = request.mutate().contextPath(apiPrefix).build();
            ServerWebExchange newExChange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExChange);
        } else {
            throw new RuntimeException(HttpStatus.NOT_FOUND, "路径有误");
        }
    }

}

第二个网关全局过滤器:仅网关转发的请求经过:

@Component
@Slf4j
public class GlobalRouteFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 打印请求路径
        String path = request.getPath().pathWithinApplication().value();
        String requestMethod = request.getMethodValue();

        //网关转发到其他服务器的需要移除统一加的前缀
        ServerHttpRequest newRequest = request.mutate().contextPath(StringUtils.EMPTY).build();
        ServerWebExchange newExChange = exchange.mutate().request(newRequest).build();
        return chain.filter(newExChange).then(
                Mono.fromRunnable(() -> {
                    // 参数
                    ServerHttpResponse response = exchange.getResponse();
                    int value = response.getStatusCode().value();
                    log.info("[Gateway] <=== {} {}: {}", value, requestMethod, path);
                })
        );
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

webflux配置参考

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐