Spring Boot如何配置可同时接受Enum字符串及序数值作为查询参数
Spring Boot 枚举查询参数同时支持字符串和序数(整数)传值配置方案
1. 实现通用枚举转换器工厂
通过实现Spring的ConverterFactory接口构造通用枚举转换逻辑,同时支持字符串名称和整数序数的匹配:
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.stereotype.Component; @Component public class UniversalEnumConverterFactory implements ConverterFactory<String, Enum<?>> { @Override public <T extends Enum<?>> Converter<String, T> getConverter(Class<T> targetType) { return new StringToEnumConverter<>(targetType); } private static class StringToEnumConverter<T extends Enum<?>> implements Converter<String, T> { private final Class<T> enumType; private final T[] enumValues; public StringToEnumConverter(Class<T> enumType) { this.enumType = enumType; this.enumValues = enumType.getEnumConstants(); } @Override public T convert(String source) { // 数字类型参数按枚举序数匹配 if (source.matches("\\d+")) { int ordinal = Integer.parseInt(source); if (ordinal >= 0 && ordinal < enumValues.length) { return enumValues[ordinal]; } throw new IllegalArgumentException("非法枚举序数:" + source); } // 字符串类型参数按枚举名称匹配 return (T) Enum.valueOf((Class) enumType, source.trim()); } } }
2. 注册转换器到Spring MVC配置
将转换器工厂添加到Spring格式化器注册表中使其全局生效:
import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Resource private UniversalEnumConverterFactory universalEnumConverterFactory; @Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(universalEnumConverterFactory); } }
3. 效果验证
示例枚举定义:
public enum StatusEnum { CREATED, // 序数0 PENDING, // 序数1 INPROGRESS, // 序数2 FINISHED // 序数3 }
控制器接口定义:
@RestController public class StatusController { @GetMapping("/{id}/status") public String queryStatus(@PathVariable Long id, @RequestParam StatusEnum status) { return "匹配结果:" + status.name(); } }
此时两种请求都可以正常处理:
GET <base-url>/123/status?status=INPROGRESSGET <base-url>/123/status?status=2
注意事项
- 枚举的
ordinal值和定义顺序强绑定,后续调整枚举顺序会导致已有整数传值匹配错误,稳定性要求高的场景建议自定义枚举code字段,调整转换器逻辑匹配自定义code即可。 - 可根据业务需求扩展转换逻辑,比如添加字符串忽略大小写匹配、非法值统一异常处理等。
内容的提问来源于stack exchange,提问作者Te Jas
相关产品推荐
相关产品推荐

