Java - 如何直接从 openapi 3.0 规范生成 Swagger UI
Posted
技术标签:
【中文标题】Java - 如何直接从 openapi 3.0 规范生成 Swagger UI【英文标题】:Java - how to generate Swagger UI directly from openapi 3.0 specification 【发布时间】:2019-09-07 18:30:02 【问题描述】:我有 yaml 格式的 openapi 3.0 规范和从中生成代码的应用程序。除了生成 swagger ui 外,一切正常。我使用 spring-fox 来生成它,但它似乎从控制器生成 swagger ui 2.0 版本,这些控制器是从 openapi 规范生成的。
如何直接从我的 3.0 规范而不是从控制器生成 swagger ui,这些控制器是从 3.0 openapi 规范生成的?
【问题讨论】:
好像 springfox 不支持 OAS 3.0 - github.com/springfox/springfox/issues/2022。你能推荐任何其他从规范中产生招摇的库吗? Where the Swagger pretty html code?, How to embed Swagger UI to a webpage?的可能重复 Swagger UI 在github.com/swagger-api/swagger-ui 独立提供,您可以将其与应用程序代码分开托管。您不会从 OpenAPI 规范生成它,而是使用 Swagger UI 并将其连接到您的规范。请参阅 ^^ 链接的问题。 【参考方案1】:好吧,我已经解决了这个问题(虽然解决方案很麻烦)。
首先我添加了swagger ui webjar -
<plugin>
<!-- Download Swagger UI webjar. -->
<artifactId>maven-dependency-plugin</artifactId>
<version>$maven-dependency-plugin.version</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>$swagger-ui.version</version>
</artifactItem>
</artifactItems>
<outputDirectory>$project.build.directory/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
然后我将我的 yaml 规范转换为 json 格式并复制到 swagger-ui webjar 目录:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>4.0.0-beta3</version>
<executions>
<execution>
<id>generate-spec</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>$openapi-spec-file-location</inputSpec>
<validateSpec>true</validateSpec>
<generatorName>openapi</generatorName>
<output>$project.build.directory/classes/META-INF/resources/webjars/swagger-ui/$swagger-ui.version</output>
</configuration>
</execution>
</executions>
</plugin>
接下来我们需要在 swagger-ui 中设置规范路径。根据swagger-ui API,我们可以传递spec
JSON 变量而不是url。所以要初始化这个spec
变量并编辑swagger ui渲染我在maven中使用replacer插件:
<plugin>
<!-- Replace the OpenAPI specification example URL with the local one. -->
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<!-- Static index html with swagger UI rendering and OAS in JSON format. -->
<include>$project.build.directory/classes/META-INF/resources/webjars/swagger-ui/$swagger-ui.version/index.html</include>
<include>$project.build.directory/classes/META-INF/resources/webjars/swagger-ui/$swagger-ui.version/openapi.json</include>
</includes>
<regexFlags>
<regexFlag>CASE_INSENSITIVE</regexFlag>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
<replacements>
<!-- This replacement imports spec json variable into static html page. -->
<replacement>
<token><script></token>
<value><script src="./openapi.json"> </script><script></value>
</replacement>
<!-- This part replaces url input variable with spec variable. -->
<replacement>
<token>url:\s"https:\/\/petstore\.swagger\.io\/v2\/swagger\.json"</token>
<value>spec: spec</value>
</replacement>
<replacement>
<!-- This replacement initializes spec variable, that will be passed to swagger ui index.html. -->
<token>^\</token>
<value>spec = </value>
</replacement>
</replacements>
</configuration>
</plugin>
所以在构建后的这一步,我们得到了带有 swagger ui 的静态资源。最后要做的就是用 Spring 来服务它。
@Configuration
@EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/3.22.0/");
//this method was introduced just for convenient swagger ui access. Without it swagger ui can be accessed with /index.html GET call
@Override
public void addViewControllers(ViewControllerRegistry registry)
registry.addViewController("/swagger-ui.html").setViewName("forward:/index.html");
原来如此。如果您对此答案发表评论并指出如何简化此过程,那就太好了。
【讨论】:
谢谢谢尔盖,这也帮助我解决了我的问题。为什么 sou 选择导致 3 次替换的“spec”变量?用本地 openapi.json 替换 petstore.json url 对我来说效果很好:<replacement><token>https:\/\/petstore\.swagger\.io\/v2\/swagger\.json</token<value>openapi.json</value></replacement>
我将输出用于 gitlab pages doc。在这种情况下,我不得不删除 index.html.gz,所以实际上我修改后的 index.html 被拾取了。
@mineralf thx,我会检查一下。我还计划检查如何从多个规范文件构建 swagger UI。找到解决办法后会在这里贴出来以上是关于Java - 如何直接从 openapi 3.0 规范生成 Swagger UI的主要内容,如果未能解决你的问题,请参考以下文章
如何从 OpenAPI 3.0 yaml 文件生成 JSON 示例?
如何在 Gradle 中为 OpenAPI 3.0 使用 Swagger Codegen?
如何使用 Springdoc 在 OpenAPI 3.0 中创建链接?
Java Enum 上的 OpenAPI 和 @Schema 注释
使用 Spring Security 启用 Swagger springdoc-openapi-ui (OpenAPI 3.0) - 无法访问 swagger-ui.html (401)