将Swagger Codegen生成的服务器存根插入现有Spring应用程序的最佳方法是什么?
我首先尝试使用petstore stubs示例。
我的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.
}
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.
}
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.
}
如何将io.swagger.configuration
包中的配置类部分包含到现有的应用程序中?
更多细节:
我遇到的问题之一是,如果我在petshop存根上指定maven依赖项(通过从mvn install:install-file ...
目录在本地安装maven):
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-spring-mvc-server</artifactId>
<version>1.0.0</version>
</dependency>
然后,我的spring应用程序找到了两个AbstractAnnotationConfigDispatcherServletInitializer
(一个来自我的应用程序,一个来自io.swagger.configuration.WebApplication
,一个来自swagger-spring-mvc-server
),并且无法加载--给出了以下例外:
注册名为“dispatcher”的servlet失败。检查是否有另一个servlet在同一名称下注册。
我想另一种表达我的问题的方法是,如何使用swagger-codegen
生成的服务器存根?看上去我不能只依靠盒子里的maven包.
发布于 2019-02-25 04:56:06
我可以看到,这是一个相当古老的,但我与此斗争了很多,我收集的信息可能对其他人有用,直到生成器文档得到改善。
本说明用于使用OpenApi生成器maven插件从openapi 3.0.0规范生成和使用spring服务器存根。
<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>
有两种配置是很难搞清楚的。
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
设置为true。这个我很喜欢!这将生成一个额外的委托接口,您的服务器控制器可以实现这个接口。生成的ApiController将将所有服务调用委托给这个接口,因此您可以非常优雅地插入您的实现。在我的设置中,我有这样的链: MessageApi (generated ) -> MessageApiController实现MessageApi (generated控制器) -> MessageApiDelegate (generated ) -> MessageService实现MessageApiDelegate (my implements )。
有了这两块配置,就不需要修改生成的源代码了。如果api规范更改了委托接口,那么您必须在MessageService中实现这些更改。
下面是对我原来文章的更新,以便更详细地解释服务实现如何绑定到委托接口。
openapi-gen生成的源位于单独的jar模块中,仅包含swagger.yaml和pom.xml作为签入的“源”。使用生成的代码的模块是一个war,它直接依赖于生成的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)
快速引擎/头文件的相关部分
<project>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>eu.dorsum.core.java.swift-engine</groupId>
<artifactId>swift-engine-service</artifactId>
</dependency>
</dependencies>
</project>
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
}
}
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 {
...
}
https://stackoverflow.com/questions/36742362
复制相似问题