Springdoc v2中Swagger枚举RecordType传参转换失败(枚举不可修改)
解决Spring Boot 3 + Springdoc v2下不可修改枚举的参数转换与Swagger显示问题
问题背景
使用Springdoc v2(Swagger-UI)、Spring Boot 3、Spring Framework 6环境,接口/api/internal/entity/number的recordType参数在Swagger-UI中显示为包含完整toString()内容的下拉选项,但调用接口时传递的字符串无法自动转换为RecordType枚举,触发报错:
Failed to convert the value of type 'java.lang.String' to required type 'com.x.x.Recordtype'
且RecordType为反编译文件,无法直接修改。
核心原因
- Spring默认的枚举转换逻辑是匹配枚举的
name()值,但当前Swagger传递的是枚举toString()方法返回的长字符串,无法匹配; - 枚举类无法修改,无法添加
@JsonCreator或内置转换逻辑。
解决方案
1. 自定义枚举转换器,实现Spring类型转换
创建Converter实现类,手动实现字符串到RecordType的转换逻辑,支持匹配枚举的recordType字段或枚举名称:
import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; @Component public class RecordTypeConverter implements Converter<String, RecordType> { @Override public RecordType convert(String source) { if (source == null || source.isBlank()) { return null; } // 遍历枚举实例,匹配传入的字符串 for (RecordType type : RecordType.values()) { if (type.getRecordType().equals(source) || type.name().equals(source)) { return type; } } throw new IllegalArgumentException("无效的RecordType值: " + source); } }
将转换器注册到Spring MVC格式化器中:
import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new RecordTypeConverter()); } }
2. 调整Swagger-UI的枚举选项显示
默认Springdoc会用枚举的toString()生成下拉选项,导致传递的字符串无法匹配。创建自定义Swagger模型转换器,让下拉选项显示正确的字符串值:
import io.swagger.v3.core.converter.AnnotatedType; import io.swagger.v3.core.converter.ModelConverter; import io.swagger.v3.core.converter.ModelConverterContext; import io.swagger.v3.oas.models.media.StringSchema; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @Component public class RecordTypeSchemaConverter implements ModelConverter { @Override public io.swagger.v3.oas.models.media.Schema resolve(AnnotatedType annotatedType, ModelConverterContext context, Iterator<ModelConverter> chain) { // 仅处理RecordType枚举 if (annotatedType.getType() instanceof Class<?> && RecordType.class.isAssignableFrom((Class<?>) annotatedType.getType())) { StringSchema schema = new StringSchema(); List<String> enumOptions = new ArrayList<>(); // 收集枚举的recordType字段作为选项值 for (RecordType type : RecordType.values()) { enumOptions.add(type.getRecordType()); } schema.setEnum(enumOptions); schema.setDescription("可选值:" + String.join(", ", enumOptions)); return schema; } // 其他类型沿用默认转换逻辑 return chain.hasNext() ? chain.next().resolve(annotatedType, context, chain) : null; } }
效果验证
- Swagger-UI的
recordType下拉列表将显示BILL、LAW两个简洁选项; - 用户选择选项后,接口接收的字符串值会通过自定义转换器自动转换为
RecordType枚举实例,不再触发类型转换错误。
内容的提问来源于stack exchange,提问作者Shambhav Agrawal
相关产品推荐
相关产品推荐

