将Swagger服务器存根添加到现有的Spring应用程序中

jlb*_*jlb 10 spring-mvc swagger springfox

Swagger Codegen生成的服务器存根插入现有Spring MVC应用程序的最佳方法是什么?

我开始试图使用petstore存根样本.

我的Spring配置是用Java编写的,如下所示:

public class SpringConfigurationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { ApplicationContext.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebMvcContext.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    // ... onStartup etc.

}
Run Code Online (Sandbox Code Playgroud)

WebMvcConfigurationSupport:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@PropertySource({ "classpath:config.properties", "file:${CONFIGDIR}/config.properties" })
@ComponentScan(useDefaultFilters = false, basePackages = { "com.yyy", "com.xxx" }, includeFilters = { @Filter(type = FilterType.ANNOTATION, value = Controller.class) })
public class WebMvcContext extends WebMvcConfigurationSupport {

    // ... beans etc.
}
Run Code Online (Sandbox Code Playgroud)

ApplicationContext的:

@Configuration
@EnableAsync
@EnableScheduling
@EnableMBeanExport
@Import({SecurityConfig.class, GeneralDBConfiguration.class})
@ComponentScan(useDefaultFilters = true, basePackages = { "com.yyy", "com.xxx" }, excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = {Controller.class, Configuration.class/*, Aspect.class*/}) })
public class ApplicationContext implements AsyncConfigurer {

    // beans etc.

}
Run Code Online (Sandbox Code Playgroud)

如何将io.swagger.configuration包的配置类部分包含到我现有的应用程序中?

更多细节:

我遇到的一个问题是,如果我在petshop存根上指定maven依赖(通过mvn install:install-file ...spring-mvc-j8-async目录运行本地安装):

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-spring-mvc-server</artifactId>
        <version>1.0.0</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

然后我的spring应用程序找到两个AbstractAnnotationConfigDispatcherServletInitializers(一个来自我的应用程序,io.swagger.configuration.WebApplication一个来自swagger-spring-mvc-server)并且无法加载 - 给出以下异常:

无法注册名为'dispatcher'的servlet.检查是否有另一个以相同名称注册的servlet.

我想用另一种方式来表达我的问题就是,你如何使用由...生成的服务器存根swagger-codegen?看起来我不能仅仅依赖于开箱即用的maven包......

Pet*_*ter 6

我可以看到这是一个很旧的,但我在这方面挣扎了很多,我收集的信息可能对其他人有用,直到生成器文档得到改进。

此描述用于使用 openapi-generator-maven-plugin 从 OpenApi 3.0.0 规范生成和使用 spring-mvc 服务器存根。

  1. 不要使用 swagger-codegen,而是使用 openapi 生成器:https : //github.com/OpenAPITools/openapi-generator(分叉的原因在这里:https : //github.com/OpenAPITools/openapi-generator/blob/主/文档/qna.md )

  2. 为服务器内容创建一个单独的项目/模块并配置 maven 插件。

<build>
    <plugins>
        <plugin>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>3.3.4</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <skipIfSpecIsUnchanged>true</skipIfSpecIsUnchanged>
                        <inputSpec>${engine-openapi-spec.location}</inputSpec>
                        <output>${project.build.directory}/generated-sources/openapi</output>
                        <generatorName>spring</generatorName>
                        <library>spring-mvc</library>
                        <apiPackage>eu.dorsum.swift.engine.service.api</apiPackage>
                        <modelPackage>eu.dorsum.swift.engine.service.model</modelPackage>
                        <generateApis>true</generateApis>
                        <generateApiDocumentation>false</generateApiDocumentation>
                        <generateApiTests>false</generateApiTests>
                        <generateModels>true</generateModels>
                        <generateModelDocumentation>false</generateModelDocumentation>
                        <generateModelTests>false</generateModelTests>
                        <generateSupportingFiles>true</generateSupportingFiles>
                        <configOptions>
                            <sourceFolder>src/main/java</sourceFolder>
                            <java8>true</java8>
                            <dateLibrary>java8</dateLibrary>
                            <useTags>true</useTags>
                            <configPackage>eu.dorsum.swift.engine.appconfig</configPackage>
                            <interfaceOnly>false</interfaceOnly>
                            <delegatePattern>true</delegatePattern>
                        </configOptions>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

有两种配置很难弄清楚。

2.a:设置configOptions/configPackage为应用程序根配置所在的包。此选项将额外basePackage添加你的配置包组件扫描在OpenAPIUiConfiguration.java: @ComponentScan(basePackages = {"eu.dorsum.swift.engine.service.api", "eu.dorsum.swift.engine.appconfig"})。这是一种反向方法,您最初可能会想到通过生成的 mvc 配置启动现有的东西,但这是我发现不需要修改生成的代码的唯一方法。

2.b:设置configOptions/delegatePattern为真。这个我非常喜欢!这将生成一个额外的委托接口,您的服务器控制器可以实现该接口。生成的 ApiController 会将所有服务调用委托给该接口,因此您可以非常优雅地插入您的实现。在我的设置中,我有这个链:MessageApi(生成的接口)-> MessageApiController 实现 MessageApi(生成的 mvc 控制器)-> MessageApiDelegate(生成的接口)-> MessageService 实现 MessageApiDelegate(我的服务方法实现)。

有了这两个配置,就不需要修改生成的源。如果 api 规范更改委托接口更改,您必须在 MessageService 中实现这些更改。

下面是对我的原始帖子的更新,以更详细地解释服务实现如何绑定到委托接口。

openapi-gen 生成的源代码位于单独的 jar 模块中,仅包含 swagger.yaml 和 pom.xml 作为签入的“源代码”。使用生成代码的模块是一个直接依赖于生成的 jar 的 war。服务实现在战争中,并在生成的源中实现 MessageApiDelegate 接口。Spring 上下文是从生成的代码中拉出来的,你在 openapi-gen config 中定义为 apiPackage 和 configPackage 的包将被添加为生成的 OpenAPIUiConfiguration.java 中 @ComponentScan 的 basePackages,所以你的服务实现必须放在 apiPackages 中或之下。

这是将各个部分放在一起的简化结构。

parent/
  swift-engin-service/ (generated jar module)
    swagger.yaml
    pom.xml
    target/generated-sources/openapi/src/main/java/eu/dorsum/swift/engine/
      appconfig/ (generated spring webmvc config)
        OpenAPIUiConfiguration.java
        WebApplication.java (brings up spring context by extending AbstractAnnotationConfigDispatcherServletInitializer)
      service/
        MessageApiController.java (@Controller, @RequestMapping etc.)
        MessageApiDelegate.java (implement this to get your service implementation plugged in the controller)
  swift-engine/ (war module, your code)
    pom.xml
    src/main/java/eu/dorsum/swift/engine/
      appconfig/
        EngineConfig.java (my spring config)
      service/api/ (must be the same as apiPackages property)
        MessageService.java (service implementation)
Run Code Online (Sandbox Code Playgroud)

swift-engine/pom.xml 的相关部分

<project>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>eu.dorsum.core.java.swift-engine</groupId>
            <artifactId>swift-engine-service</artifactId>
        </dependency>
    </dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)

eu.dorsum.swift.engine.service.api.MessageService 的相关部分

@Service
public class MessageService implements MessageApiDelegate {
    @Override
    public ResponseEntity<List<SwiftMessage>> listMessages(List<String> sorting, Integer pageStart, Integer pageSize, String filter) {
        // implementation
    }

    @Override
    public ResponseEntity<Void> updateMessage(SwiftMessage message) {
        // implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

eu.dorsum.swift.engine.appconfig.OpenAPIUiConfiguration 的相关部分(生成)

@Configuration
@ComponentScan(basePackages = {"eu.dorsum.swift.engine.service.api", "eu.dorsum.swift.engine.appconfig"})
@EnableWebMvc
public class OpenAPIUiConfiguration extends WebMvcConfigurerAdapter {
    ...
}
Run Code Online (Sandbox Code Playgroud)