SpringBoot3 - Spring Doc 2.0 Migration

在将SpringDoc从1.x升级到2.0以支持SpringBootV3时,遇到SwaggerUI无法渲染定义的问题。错误信息提示缺少有效的Swagger或OpenAPI版本字段。问题源于返回值从String变为byte[],导致StringHttpMessageConverter无法处理。解决方案是调整MessageConverter的顺序,将ByteArrayMessageConverter放在MappingJackson2HttpMessageConverter之前,从而解决SwaggerUI的解析问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Doc 2.0 Migration

For spring-boot v3 support, make sure you use springdoc-openapi v2
这是springdocgithub主页上留一下的一句话(https://github.com/springdoc/springdoc-openapi),看起来springdoc 1.x不支持Springboot3,我们按照官网的指引进行相关pom的替换

<dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.0.4</version>
   </dependency>

然后重启服务打开我们的swagerUI,不出意外的出意外了

Unable to render this definition The provided definition does not specify a valid version field.

Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).

在这里插入图片描述

问题排查

查了半天,作者的说法是MessageConvert有问题,需要使用MappingJackson2HttpMessageConverter,看了一下我们的配置,似乎也没有问题

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.TEXT_HTML));
        stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false);
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper);
        mappingJackson2HttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);

        //stringHttpMessageConverter is first, mappingJackson2HttpMessageConverter is second than default converters
        //mappingJackson2HttpMessageConverter should behind byteConverter for springDoc
        converters.add(0, mappingJackson2HttpMessageConverter);
        converters.add(0, stringHttpMessageConverter);
    }

然后我尝试访问了/api-docs这个接口,正常会返回一个json,但是在这里我得到了一个Base64编码之后的字符串
在这里插入图片描述
对Base64接码之后正是我们需要的Json,看起来确实是Converter这里出了问题。

随后我们对两个版本进行debug,发现了问题所在
首先是SpringDoc 1.6.x
在这里插入图片描述
这里可以看到返回的是一个String,实际上就是一个json字符串,这个json会被排在第一的StringHttpMessageConverter处理返给HttpResponse,页面可以正常展示。
然后我们转到SpringDoc 2.x
在这里插入图片描述

可以看到返回值变成了一个byte[]StringHttpMessageConverter不会处理byte数组,转而走到了排在第二的MappingJackson2HttpMessageConverter,在这里会将byte数组转为base64字符串,SwagerUI无法解析导致了问题的产生。

又是什么原因导致了open-api的返回值发生了改变,比较一下两个版本的OpenApiWebMvcResource就可以找到原因

//1.6.x
  @Operation(
        hidden = true
    )
    @GetMapping(
        value = {"${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}"},
        produces = {"application/json"}
    )
    public String openapiJson(HttpServletRequest request, @Value("${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}") String apiDocsUrl, Locale locale) throws JsonProcessingException {
        return super.openapiJson(request, apiDocsUrl, locale);
    }
//2.0.x
@Operation(hidden = true)
	@GetMapping(value = API_DOCS_URL, produces = MediaType.APPLICATION_JSON_VALUE)
	@Override
	public byte[] openapiJson(HttpServletRequest request, @Value(API_DOCS_URL) String apiDocsUrl, Locale locale)
			throws JsonProcessingException {
		return super.openapiJson(request, apiDocsUrl, locale);
	}

其实就是SpringDoc自己把返回值改了。

问题解决

SpingDoc的代码我们没有办法修改,但是我们可以在MessageConvert上入手。通过debug我们发现,Spring本身会为我们配置一些convert

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     converters.add(0, mappingJackson2HttpMessageConverter);
        converters.add(0, stringHttpMessageConverter);
    }

这里的converters中第一个就是ByteArrayMessageConverter,只是在我们的配置中把他排到了第三个,重新调整一下位置将它排在前面问题得以解决

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值