Spring端点能否同时支持大小写形式的枚举常量?
Spring Boot枚举请求参数大小写兼容解决方案
问题场景
现有Spring Boot控制器端点定义如下:
@GetMapping(path = "/{custId}/items", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @AuthorizationValidationStrategy public List<ItemDTO> getCustItemsByItemType( @PathVariable @SecureResource(CUST) Long custId, @RequestParam("itemType") List<ItemType> itemTypes ) { return this.myFeignClient.findItemsByCustIdAndItemTypes(custId, itemTypes); }
其中ItemType为全大写枚举常量,当前端点仅支持传入大写枚举值(如http://127.0.0.1:8080/1.0/custs/2/items?itemType=BREAD),传入小写值(如http://127.0.0.1:8080/1.0/custs/2/items?itemType=bread)时会直接抛出异常。已通过@JsonCreator实现枚举的大小写不敏感解析,但该逻辑未生效——因为请求参数的解析阶段早于JSON处理阶段,@JsonCreator仅作用于请求体的JSON解析。
解决方案
方案一:全局注册自定义Converter
创建一个实现Converter<String, ItemType>的类并注册为Spring组件,Spring MVC会自动用它处理请求参数到枚举的转换:
import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; @Component public class ItemTypeConverter implements Converter<String, ItemType> { @Override public ItemType convert(String source) { if (source == null || source.isBlank()) { return null; } // 将输入转为大写后匹配枚举 return ItemType.valueOf(source.toUpperCase()); } }
该方案对整个应用的所有ItemType类型请求参数生效。
方案二:控制器局部注册PropertyEditor
如果仅需要当前控制器生效,可在控制器类中添加@InitBinder方法注册自定义PropertyEditor:
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(ItemType.class, new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(ItemType.valueOf(text.toUpperCase())); } }); }
关键说明
@JsonCreator仅负责处理请求体中的JSON数据解析,而@RequestParam对应的URL参数是由Spring MVC的参数解析器(RequestParamMethodArgumentResolver)处理,依赖的是Spring的Converter或PropertyEditor体系,因此之前的@JsonCreator逻辑不会作用于URL请求参数。
内容的提问来源于stack exchange,提问作者user22592482
相关产品推荐
相关产品推荐

