我在 Spring Boot 应用程序上为私有 API 配置了 swagger。这些端点是用弹簧制成的。
在同一台服务器上还有一个公共 API,其端点是用 Jersey 制作的。
我为这个公共 API 配置了一个 swagger,它似乎可以工作。
当我访问 http://localhost:8080/@context.root@/swagger-ui/index.html 时,我可以看到定义
不过我觉得配置有点“奇怪”,可以改进一下。
事实上,openapi.json 文件是以两种不同的方式创建的,我很确定这两个 API 的 swagger 配置可能是相同的。
我想使用
GroupedOpenApi
类为球衣资源(公共 API)配置 swagger,并从 application.yml
中删除所有 url 配置,但到目前为止未成功...
spring boot版本:2.7.0但计划下个月升级到v3
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.2</version>
</dependency>
为使用 spring 端点制作的私有 api 配置 swagger“02 - private”
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.SpringDocUtils;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
@Configuration
public class SwaggerConfiguration implements WebMvcConfigurer {
private static final String FORWARD_SWAGGER_UI_HTML = "forward:/swagger-ui.html";
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/swagger").setViewName(FORWARD_SWAGGER_UI_HTML);
registry.addViewController("/swagger/").setViewName(FORWARD_SWAGGER_UI_HTML);
registry.addViewController("/swagger-ui").setViewName(FORWARD_SWAGGER_UI_HTML);
registry.addViewController("/swagger-ui/").setViewName(FORWARD_SWAGGER_UI_HTML);
}
@Bean
public OpenAPI openApiDefinition(final AppProperties properties) {
SpringDocUtils.getConfig().replaceWithClass(LocalDate.class, String.class);
SpringDocUtils.getConfig().replaceWithClass(LocalDateTime.class, String.class);
return new OpenAPI()
.addServersItem(new Server().url("/" + properties.getContextRoot()))
.info(new Info().title(properties.getAppName()));
}
@Bean
public GroupedOpenApi privateApi(final AppProperties properties) {
return GroupedOpenApi.builder()
.group("02 - private")
.pathsToMatch("/api/**")
.pathsToExclude("/api/pub/*")
.addOpenApiCustomiser(this.customizeApiPrivate(properties))
.build();
}
private OpenApiCustomiser customizeApiPrivate(final AppProperties properties) {
return (final OpenAPI openApi) -> openApi.getInfo()
.title("Private API title")
.description("Private API description")
.version(properties.getAppVersion());
}
// This create "01 - public" but with empty endpoints / operations,
// it seems like jersey endpoints are just ignored if swagger is configured this way
/**
@Bean
public GroupedOpenApi publicApi(final AppProperties properties) {
return GroupedOpenApi.builder()
.group("01 - public")
.pathsToMatch("/api/pub/**")
.packagesToScan("path.to.resources.package.api.pub")
.addOpenApiCustomiser(...)
.build();
}
*/
}
为公共api“01 - public”配置openapi.json的位置
springdoc:
swagger-ui:
disable-swagger-default-url: true
defaultModelExpandDepth: 3
operationsSorter: "alpha"
tagsSorter: "alpha"
urls:
- name: '01 - public'
url: '/@context.root@/swagger-ui/pub/openapi.json'
配置球衣端点+为公共api的swagger添加映射
@EnableWebMvc
@Configuration
@PropertySources(...)
@ComponentScan(...)
@ConfigurationPropertiesScan(...)
public class AppConfiguration implements WebMvcConfigurer {
@Bean
public ServletRegistrationBean<ServletContainer> publicJersey(AppProperties properties)
{
ServletRegistrationBean<ServletContainer> pubJersey = new ServletRegistrationBean<>(
new ServletContainer(new ApiPublicJerseyConfig(properties)));
pubJersey.addUrlMappings("/api/pub/*","/swagger-ui/pub/*");
pubJersey.setLoadOnStartup(0);
return pubJersey;
}
...
}
为使用 jersey 端点创建的公共 api 配置 swagger“01 - public”
import org.glassfish.jersey.server.ResourceConfig;
import io.swagger.v3.core.converter.ModelConverters;
import io.swagger.v3.jaxrs2.integration.resources.BaseOpenApiResource;
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
import io.swagger.v3.oas.integration.SwaggerConfiguration;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
public class ApiPublicJerseyConfig extends ResourceConfig {
public ApiPublicJerseyConfig(AppProperties properties) {
super();
packages("path.to.resources.package.api.pub");
register(swaggerConfig(properties));
}
private static BaseOpenApiResource swaggerConfig(AppProperties properties) {
return new OpenApiResource().openApiConfiguration(
new SwaggerConfiguration()
.resourcePackages(new HashSet<>(Collections.singletonList("path.to.resources.package.api.pub")))
.openAPI(publicOpenApi(properties))
);
}
private static OpenAPI publicOpenApi(final AppProperties properties) {
return new OpenAPI()
.addServersItem(new Server().url("/" + properties.getContextRoot() + "/api/pub"))
.info(new Info()
.title("Public API title")
.description("Public API description")
.version(properties.getAppVersion())
);
}
}
好吧,我想我在这里得到了答案https://springdoc.org/faq.html 看来我不能对两种 servlet 类型(Spring 和 Jersey)使用相同类型的 swagger 配置
springdoc-openapi支持Jersey吗?
如果您使用 JAX-RS 并作为 实现 Jersey (例如@Path),我们不支持它。
我们仅支持使用 Spring 托管 bean 公开 Rest 端点 (例如@RestController)。
你可以看看 swagger-jaxrs2 项目:
https://github.com/swagger-api/swagger-samples/tree/2.0/java/java-jersey2-minimal