如何配置Springdoc使/api-docs默认返回YAML格式而非JSON
让Springdoc默认返回YAML格式的OpenAPI文档(Spring Boot 3.x)
直接用Springdoc提供的配置属性就能搞定,不用写复杂的控制器或过滤器,步骤如下:
方案1:配置默认响应媒体类型
在你的application.yml或者application.properties里添加以下配置:
- 若用yaml配置:
springdoc: api-docs: default-produces-media-type: application/yaml
- 若用properties配置:
springdoc.api-docs.default-produces-media-type=application/yaml
这个配置会直接修改/api-docs端点的默认响应类型,访问时无需加后缀就会返回YAML格式。
为什么之前的尝试没生效?
你之前写的自定义控制器被Springdoc自带的OpenApiResource控制器覆盖了,因为它的请求映射优先级更高。而过滤器的方式可能没正确处理请求的Accept头或者响应的Content-Type,所以没起作用。
备选方案:自定义端点(配置属性不生效时)
如果上面的配置没起作用(比如某些特殊版本兼容问题),可以自定义一个端点来直接返回YAML格式的文档:
@RestController @RequestMapping("/api-docs") public class CustomOpenApiController { private final OpenApiResource openApiResource; public CustomOpenApiController(OpenApiResource openApiResource) { this.openApiResource = openApiResource; } @GetMapping(produces = "application/yaml") public ResponseEntity<String> getOpenApiYaml() { String yamlContent = openApiResource.openapiYaml(null, null); return ResponseEntity.ok() .contentType(MediaType.parseMediaType("application/yaml")) .body(yamlContent); } }
然后需要排除Springdoc自带的/api-docs端点,在配置类里添加:
@Configuration public class SpringDocConfig { @Bean public OpenAPI customOpenAPI() { return new OpenAPI() .info(new Info().title("Your API").version("v1")); } @Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("public") .pathsToMatch("/**") .build(); } // 排除默认的/api-docs端点 @Bean public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) { List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>(); Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints(); allEndpoints.addAll(webEndpoints); allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); String basePath = webEndpointProperties.getBasePath(); EndpointMapping endpointMapping = new EndpointMapping(basePath); boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath); return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null) { @Override protected boolean isHandler(Class<?> beanType) { // 排除OpenApiResource的处理 return !OpenApiResource.class.isAssignableFrom(beanType) && super.isHandler(beanType); } }; } }
不过这个方案比较繁琐,优先用方案1的配置属性更简单。
内容的提问来源于stack exchange,提问作者Rubén Osmar Alvarado
相关产品推荐
相关产品推荐

