You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Spring API Gateway访问Swagger的重定向问题咨询

问题解决:API网关后Swagger重定向地址异常

问题场景

我有一个运行在localhost:8080的user service微服务,以及部署在localhost:8765的网关,路由配置如下:

@Bean
public RouteLocator gatewayRouter(RouteLocatorBuilder routeLocatorBuilder){
    return routeLocatorBuilder
            .routes()
            .route(predicateSpec -> predicateSpec
                            .path("/user-service/**")
                            .filters(
                                    gatewayFilterSpec -> gatewayFilterSpec
                                            .rewritePath("/user-service/(?<segment>.*)", "/${segment}")
                            )
                            .uri("lb://USER-SERVICE")
            )
            .route(predicateSpec -> predicateSpec
                    .path("/location-service/**")
                    .filters(
                            gatewayFilterSpec -> gatewayFilterSpec
                                    .rewritePath("/location-service/(?<segment>.*)", "/${segment}")
                    )
                    .uri("lb://LOCATION-SERVICE")
            )
            .build();
}

直接访问localhost:8080/swagger-ui.html时,会正常重定向到http://localhost:8080/swagger-ui/index.html#/,可正常访问Swagger。但通过API网关访问localhost:8765/user-service/swagger-ui.html时,重定向会指向网关地址http://localhost:8765/swagger-ui/index.html,而非带网关前缀的路径,导致无法正常访问Swagger界面。


解决方案

方案一:网关层面修改重定向响应头

在网关的user-service路由中添加自定义过滤器,修改重定向的Location头,补全网关的路由前缀:

.route(predicateSpec -> predicateSpec
        .path("/user-service/**")
        .filters(gatewayFilterSpec -> gatewayFilterSpec
                .rewritePath("/user-service/(?<segment>.*)", "/${segment}")
                // 处理Swagger重定向的Location头,添加网关前缀
                .modifyResponseBody(String.class, String.class, (exchange, body) -> {
                    HttpHeaders headers = exchange.getResponse().getHeaders();
                    if (headers.containsKey(HttpHeaders.LOCATION)) {
                        String originalLocation = headers.getFirst(HttpHeaders.LOCATION);
                        if (originalLocation.startsWith("/swagger-ui/")) {
                            headers.set(HttpHeaders.LOCATION, "/user-service" + originalLocation);
                        }
                    }
                    return Mono.just(body);
                })
        )
        .uri("lb://USER-SERVICE")
)

该过滤器会检测响应中的Location头,若是Swagger的重定向地址,自动补上/user-service前缀,让重定向路径符合网关的路由规则。

方案二:在User Service中配置Swagger的Base URL

让Swagger生成的所有路径都带上网关的路由前缀,从根源上解决重定向地址问题。在User Service的Swagger配置类中添加Server配置:

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.your.user.service.package"))
                .paths(PathSelectors.any())
                .build()
                .servers(List.of(new Server("/user-service", "User Service via API Gateway")));
    }
}

配置后,Swagger返回的重定向地址会自动包含/user-service前缀,Location响应头将是http://localhost:8765/user-service/swagger-ui/index.html#/,直接匹配网关路由。

方案三:禁用Swagger自动重定向,直接返回HTML

在User Service中添加一个控制器,将/swagger-ui.html请求直接转发到/swagger-ui/index.html,避免发送重定向响应:

@Controller
public class SwaggerForwardController {
    @GetMapping("/swagger-ui.html")
    public String forwardToSwaggerIndex() {
        return "forward:/swagger-ui/index.html";
    }
}

这样请求/user-service/swagger-ui.html时,服务会直接返回Swagger界面的HTML内容,不会触发重定向,也就不会出现地址错误问题。


内容的提问来源于stack exchange,提问作者Ippili Akarsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:10:28