如何为 swagger 2.8.0 做友好的基本 url

Posted

技术标签:

【中文标题】如何为 swagger 2.8.0 做友好的基本 url【英文标题】:how to do friendly base url for swagger 2.8.0 【发布时间】:2018-09-30 03:29:24 【问题描述】:

我正在尝试更改 API 文档的基本访问 URL。网址是“http://localhost:8080/swagger-ui.html”。我想得到类似“http://localhost:8080/myapi/swagger-ui.html”的东西。

我使用 Springfox 2.8.0 Swagger、Java 8、Spring Boot 2.0 大摇大摆的配置是:

@Configuration
@EnableSwagger2
public class SwaggerConfiguration 

    @Bean
    public Docket api(ServletContext servletContext) 
        return new Docket(DocumentationType.SWAGGER_2)
                .pathProvider(new RelativePathProvider(servletContext) 
                    @Override
                    public String getApplicationBasePath() 
                        return "/myapi";
                    
                )
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(Predicates.not(PathSelectors.regex("/error")))
                .build()
                .useDefaultResponseMessages(false);
    

自定义路径提供程序必须提供帮助,但我仍然可以使用 url“http://localhost:8080/swagger-ui.html”访问 api 文档。如果我使用 url "http://localhost:8080/myapi/swagger-ui.html",我会得到 404 错误。请看下面的截图。

【问题讨论】:

你有没有解决这个问题,我也遇到了同样的问题 【参考方案1】:

UPD:Springfox 已弃用

Springfox Swagger 一直是一个有点脏的解决方案,有很多不明确和错误,但到现在(2021 Q4)它已经一年多没有更新了。

最后一根稻草是Springfox Swagger 3.0 doesn't work anymore with Spring Boot 2.6.x.

因此,如果您阅读本文,请考虑改用https://springdoc.org/。

这是一个非常简单的转换,他们做得很好 记录它。 https://springdoc.org/#migrating-from-springfox.

对于使用 Springfox Swagger 3.0.0 的用户

Here's 更改文档基本网址的工作配置:

springfox:
  documentation:
    swaggerUi:
      baseUrl: /documentation
    openApi:
      v3:
        path: /documentation/v3/api-docs
    swagger:
      v2:
        path: /documentation/v2/api-docs

【讨论】:

【参考方案2】:

您可以像这样编辑您的 SwaggerConfiguration

注意更换package(必须是 包含您的 REST 控制器)、host 和您需要的 PATH

@Configuration
@EnableSwagger2
public class SwaggerConfiguration implements WebMvcConfigurer 

    public static final String PATH = "/myapi";

    @Bean
    public Docket api() 
        final var package = "com.julia.rest";
        final var host = "localhost:8080";

        return new Docket(DocumentationType.SWAGGER_2)
                .host(host)
                .select()
                .apis(RequestHandlerSelectors.basePackage(package))
                .paths(PathSelectors.any())
                .build();
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        final var apiDocs = "/v2/api-docs";
        final var configUi = "/swagger-resources/configuration/ui";
        final var configSecurity = "/swagger-resources/configuration/security";
        final var resources = "/swagger-resources";

        registry.addRedirectViewController(PATH + apiDocs, apiDocs).setKeepQueryParams(true);
        registry.addRedirectViewController(PATH + resources, resources);
        registry.addRedirectViewController(PATH + configUi, configUi);
        registry.addRedirectViewController(PATH + configSecurity, configSecurity);
        registry.addRedirectViewController(PATH, "/");
    

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        registry.addResourceHandler(PATH + "/**").addResourceLocations("classpath:/META-INF/resources/");
    

另一种解决方案是更改 spring-boot URL context-path

编辑倒application.properties文件:

server.servlet.context-path=/myapi

或者如果你有一个application.yml 文件:

server:
  servlet:
    context-path: /myapi

警告:它会改变你所有网络服务的基本路径,而不仅仅是 Swagger

【讨论】:

【参考方案3】:

https://github.com/springfox/springfox/issues/2250 - 正如他们所说,您可以配置重定向到您自己的路径

【讨论】:

【参考方案4】:

我也遇到过这个问题并尝试了许多可能的解决方案,但没有任何帮助。 在我的情况下,我不能使用任何资源重定向,因为 swagger 必须可以通过匹配路径 /api-docs/** 在本地访问,就像在谷歌云上一样。在我的情况下,在谷歌云上任何资源重定向都将被拒绝。所有资源也必须从此路径加载 这是我的解决方案: springfox-swagger2 和 springfox-swagger-ui 2.9.2 版本

@EnableSwagger2
@Configuration
public class SwaggerCommonConfig implements WebMvcConfigurer 
    public static final String PATH = "/api-docs";

    @Bean
    public Docket api() 
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addRedirectViewController(PATH, "/");
    

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        registry.addResourceHandler(PATH + "/**").addResourceLocations("classpath:/META-INF/resources/");
    


并且由于 springfox 没有任何可能以其他方式做到这一点,在我的例子中,我们将创建简单的控制器,将资源请求从我们的自定义路径转换为标准 springfox。 (这不是很优雅的部分,但它就是这样:))

@RestController
@RequestMapping(SwaggerGatewayCommonConfig.PATH)
@RequiredArgsConstructor
public class SwaggerController 
    private final RestTemplate restTemplate;
    private final static String V2_API_DOCS = "/v2/api-docs";
    private final static String SWAGGER_RESOURCES_CONFIGURATION_UI = "/swagger-resources/configuration/ui";
    private final static String SWAGGER_RESOURCES_CONFIGURATION_SECURITY = "/swagger-resources/configuration/security";
    private final static String SWAGGER_RESOURCES = "/swagger-resources";
    private final static Pattern pattern = Pattern.compile("http[s]*://([^/]+)", Pattern.CASE_INSENSITIVE);

    @Value("$server.port")
    private String port;

    @GetMapping(V2_API_DOCS)
    @SuppressWarnings("unchecked")
    public Map<String, Object> getV2ApiDocs(HttpServletRequest request) 
        Matcher matcher = pattern.matcher(request.getRequestURL().toString());
        matcher.find();

        Map<String, Object> resp = (Map<String, Object>) restTemplate.getForObject(toLocalSwaggerUrl(V2_API_DOCS), Map.class);
        //we have to replace standard host, to requested host. as swagger UI make api requests from this host
        resp.put("host", matcher.group(1));

        return resp;
    

    @GetMapping(SWAGGER_RESOURCES_CONFIGURATION_UI)
    public Object getSwaggerResourcesConfigurationUi() 
        return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES_CONFIGURATION_UI), Object.class);
    

    @GetMapping(SWAGGER_RESOURCES_CONFIGURATION_SECURITY)
    public Object getSwaggerResourcesConfigurationSecurity() 
        return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES_CONFIGURATION_SECURITY), Object.class);
    

    @GetMapping(SWAGGER_RESOURCES)
    public Object getSwaggerResources() 
        return restTemplate.getForObject(toLocalSwaggerUrl(SWAGGER_RESOURCES), Object.class);
    

    private String toLocalSwaggerUrl(String path) 
        return "http://localhost:" + port + path;
    

我希望它也会为遇到它的人节省时间 =) 祝你好运

【讨论】:

【参考方案5】:

Swagger 基本访问 url 是从您的基本应用程序路径构建的。因此,如果您更改基本应用程序路径,您将获得所需的行为。但您的所有 api 也将更改为该路径。你可以在这里找到如何更改它How to set base url for rest in spring boot?。

您所做的也改变了 swagger 从您的应用程序调用其他 api 的方式,而不是更改他的基本 url。有一些技巧可以在不更改应用程序基本路径的情况下更改 swagger 基本 url(手动移动所有 swagger 资源),但我不建议这样做。

【讨论】:

以上是关于如何为 swagger 2.8.0 做友好的基本 url的主要内容,如果未能解决你的问题,请参考以下文章

NestJs Swagger:如何为动态类定义 Api 属性

如何为内容类型的响应正文提供示例值:Swagger 中的 text/html(使用 dredd 进行测试)

如何为枚举使用用户友好的名称? [复制]

如何为默认的swagger android客户端设置连接和套接字超时

如何为文档化的 JavaScript 函数轻松创建 Github 友好的降价?

如何为 Visual Basic 6 ActiveX CLSID 设置“友好”名称