Java - 如何直接从 OpenAPI 3.0 规范生成 Swagger UI

9
我有一个yaml格式的OpenAPI 3.0规范和一个从规范生成代码的应用程序。除了生成Swagger UI之外,一切都正常。我使用Spring Fox生成Swagger UI,但似乎它从从OpenAPI规范生成的控制器中生成Swagger UI 2.0版本。
我该如何直接从我的3.0规范生成Swagger UI,而不是从生成的控制器中生成?

1
似乎 springfox 不支持 OAS 3.0 - https://github.com/springfox/springfox/issues/2022。你能推荐其他可以从规范生成 Swagger 的库吗? - Sergei Podlipaev
Swagger UI可以独立使用,您可以从https://github.com/swagger-api/swagger-ui/获取并将其与应用程序代码分开托管。您不需要从OpenAPI规范生成它,而是将Swagger UI与您的规范连接起来。请参见链接的问题。 - Helen
1个回答

12

好的,我已经解决了这个问题(虽然解决方案相当繁琐)。

首先,我添加了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中使用了替换插件:

            <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>&lt;script&gt;</token>
                            <value>&lt;script src="./openapi.json"&gt; &lt;/script&gt;&lt;script&gt;</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");
    }
}

这就是全部内容。如果您能够评论此答案并指出如何简化该过程,将会很棒。


谢谢Sergei,这对我解决问题非常有帮助。 为什么选择“spec”变量会导致3个替换?将petstore.json的URL替换为本地openapi.json对我来说完全可以: <replacement><token>https:\/\/petstore\.swagger\.io\/v2\/swagger\.json</token<value>openapi.json</value></replacement> 我将输出用于gitlab页面文档。在这种情况下,我必须删除index.html.gz,以便实际上使用我的修改后的index.html。 - Ralf
@mineralf 谢谢,我会去看一下。另外我计划查一下如何从多个规范文件构建Swagger UI。找到解决方案后会在这里发布。 - Sergei Podlipaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接