Zuul网关后Swagger UI测试页面路径重复添加/the-login问题排查
我之前在整合Zuul网关和Swagger时踩过一模一样的坑,百分百是配置没匹配好导致的路径重复。下面给你拆解原因和解决方案:
问题根源分析
你的Zuul路由已经把api-login指向了http://localhost:8070/the-login/,但如果自定义SwaggerResourcesProvider时直接引用了目标服务的Swagger地址(比如http://localhost:8070/the-login/v2/api-docs),就会触发两个路径叠加的问题:
- 目标服务的Swagger配置里,
basePath大概率是/the-login/ - Swagger UI会把这个
basePath和接口路径/LoginTest拼接,再加上Zuul转发时的路由映射,最终就变成了/the-login/the-login/LoginTest,自然返回404。
解决方案
1. 修正SwaggerResourcesProvider实现,让Swagger资源指向网关路由路径
不要直接用目标服务的地址,而是基于Zuul的前缀和路由ID构建Swagger资源的location,这样Swagger UI会基于网关路径生成请求URL,Zuul转发时会自动处理映射。示例代码:
@Component public class CustomSwaggerResourcesProvider implements SwaggerResourcesProvider { private final RouteLocator routeLocator; private final ZuulProperties zuulProperties; public CustomSwaggerResourcesProvider(RouteLocator routeLocator, ZuulProperties zuulProperties) { this.routeLocator = routeLocator; this.zuulProperties = zuulProperties; } @Override public List<SwaggerResource> get() { List<SwaggerResource> resources = new ArrayList<>(); // 遍历Zuul路由,构建网关侧的Swagger资源地址 routeLocator.getRoutes().forEach(route -> { String location = String.format("/%s/%s/v2/api-docs", zuulProperties.getPrefix(), route.getId()); SwaggerResource resource = new SwaggerResource(); resource.setName(route.getId()); resource.setLocation(location); resource.setSwaggerVersion("2.0"); resources.add(resource); }); return resources; } }
2. 检查Zuul路由配置的path规则
确保路由路径和目标服务的basePath不重复,比如你的application.yml可以这么配置:
zuul: prefix: /api routes: api-login: path: /login/** # 网关侧的路径前缀 url: http://localhost:8070/the-login/ # 目标服务地址
这样网关收到/api/login/LoginTest的请求时,会转发到http://localhost:8070/the-login/LoginTest,完美匹配目标服务的接口路径。
3. 调整目标服务的SwaggerbasePath配置
如果目标服务的Swagger配置里设置了basePath: /the-login/,建议把它改成空字符串""——因为Zuul已经负责路由到目标服务的前缀了,目标服务只需要暴露纯接口路径即可。
验证方式
你可以手动访问网关的Swagger资源地址,比如/api/api-login/v2/api-docs,查看返回的swagger.json里的basePath是否为/api/login/,如果是,那Swagger UI生成的请求路径就会完全符合Zuul的路由规则,不会再出现重复问题。
内容的提问来源于stack exchange,提问作者Phate

