java 如何更改 Springfox Swagger 2.0 的 basePath

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36198827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:03:46  来源:igfitidea点击:

How to change basePath for Springfox Swagger 2.0

javaspring-bootswagger-uiswagger-2.0springfox

提问by Martin Asenov

I'm running a service, where Swagger UI is accessible at:

我正在运行一项服务,可以在以下位置访问 Swagger UI:

http://serviceURL/swagger-ui.html

However, it is behind a proxy, such as:

但是,它是在代理后面,例如:

http://proxyURL/serviceName

Generated URLs by Swagger UI are looking like:

Swagger UI 生成的 URL 如下所示:

http://proxyURL/

instead of the actual URL with the serviceName as suffix. As far as I get it, this means manipulating the basePath property. As per documentation:

而不是以 serviceName 作为后缀的实际 URL。据我所知,这意味着操作 basePath 属性。根据文档:

A swagger API documentation can no longer describe operations on different base paths. In 1.2 and earlier, each resource could have had a separate basePath. In 2.0, the basePath equivalents (schemes+host+basePath) are defined for the whole specification.

swagger API 文档无法再描述不同基本路径上的操作。在 1.2 及更早版本中,每个资源都可以有一个单独的 basePath。在 2.0 中,为整个规范定义了 basePath 等效项(schemes+host+basePath)。

@Api(basePath) is deprecated, and it doesn't say what to use and how to use it. How to make the paths generated by Swagger appear properly?

@Api(basePath) 已弃用,它没有说明使用什么以及如何使用它。如何让 Swagger 生成的路径正确显示?

I'm using Spring Boot, Springfox Swaggerand annotations.

我正在使用SpringBoot、Springfox Swagger和注释。

回答by astafev.evgeny

@Bean
public Docket newsApi(ServletContext servletContext) {
    return new Docket(DocumentationType.SWAGGER_2).pathProvider(new RelativePathProvider(servletContext) {
        @Override
        public String getApplicationBasePath() {
            return "/serviceName" + super.getApplicationBasePath();
        }
    }).host("proxyURL");
}

回答by veben

You can edit your SwaggerConfigurationlike that:

您可以像这样编辑SwaggerConfiguration

Take care to replace the package(which need to be the one containing your REST controllers), the host, and the PATHyou need

小心替换package(必须是包含您的 REST 控制器的)host、 和PATH您需要的

@Configuration
@EnableSwagger2
public class SwaggerConfiguration implements WebMvcConfigurer {

    public static final String PATH = "/serviceName";

    @Bean
    public Docket api() {
        final var package = "com.martin.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/");
    }
}

Another solution is by changing the spring-boot URL context-path:

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

Edit pour application.propertiesfile:

编辑浇筑application.properties文件:

server.servlet.context-path=/serviceName

Or if you have an application.ymlfile:

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

server:
  servlet:
    context-path: /serviceName

Warning: It will change the base path of all your web services, not only Swagger

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

回答by Eko Prasetyo

Using spring fox 2.9.2, using solution mentioned by other users is not works.

使用 spring fox 2.9.2,使用其他用户提到的解决方案不起作用。

What is not working:

什么不起作用:

  • Overriding getApplicationBasePath on Docket pathProvider
  • Adding server.servlet.context-path=/serviceName
  • 覆盖 Docket pathProvider 上的 getApplicationBasePath
  • 添加 server.servlet.context-path=/serviceName

I don't know why they are not work, but in my project that using Springboot 2.1.6.RELEASE and Spring 5.1.8.RELEASE, the two solution above is being ignored.

我不知道为什么它们不起作用,但是在我使用 Springboot 2.1.6.RELEASE 和 Spring 5.1.8.RELEASE 的项目中,上面的两个解决方案被忽略了。

So, I am trying another approach: https://github.com/springfox/springfox/issues/2817#issuecomment-517753110

所以,我正在尝试另一种方法:https: //github.com/springfox/springfox/issues/2817#issuecomment-517753110

According to the github issue comment, I need to override Springfox json serialize class and thank god this works. Here is the code example:

根据 github 问题评论,我需要覆盖 Springfox json 序列化类,感谢上帝这是有效的。这是代码示例:

import io.swagger.models.Swagger;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import springfox.documentation.spring.web.json.HymansonModuleRegistrar;
import springfox.documentation.spring.web.json.Json;
import springfox.documentation.spring.web.json.JsonSerializer;

import java.util.Arrays;
import java.util.List;

import static io.github.jhipster.config.JHipsterConstants.SPRING_PROFILE_PRODUCTION;

@Component
@Primary
public class CustomBasePathSerialize extends JsonSerializer {

    // this injection is optional, if you don't need to
    // add basePath based on active profile, remove this.
    private final Environment env;

    public CustomBasePathSerialize(List<HymansonModuleRegistrar> modules,
                                   Environment env) {
        super(modules);
        this.env = env;
    }

    @Override
    public Json toJson(Object toSerialize) {
        if (toSerialize instanceof Swagger) {
            Swagger swagger = (Swagger) toSerialize;
            String basePath = "/serviceName";
            List<String> profiles = Arrays.asList(env.getActiveProfiles());

            // OPTIONAL: you can change basePath if you have difference path 
            // on any Spring profile, for example prod:
            if (profiles.contains(SPRING_PROFILE_PRODUCTION)) {
                basePath = "/";
            }
            swagger.basePath(basePath);
        }
        return super.toJson(toSerialize);
    }
}