Jackson反序列化枚举时如何支持数组的大小写不敏感?
解决Java枚举数组/集合反序列化大小写不敏感问题
问题本质
单个枚举字段能兼容大小写变体,大概率是Jackson的ACCEPT_CASE_INSENSITIVE_ENUMS特性已局部生效(或默认配置覆盖),但该特性默认不会自动作用于集合/数组类型的枚举字段,@JsonFormat也仅对单个枚举实例生效,无法覆盖集合场景。
三种可行解决方案
1. 全局开启枚举大小写不敏感(推荐)
直接在Jackson配置中全局开启枚举大小写兼容,所有枚举类型(包括集合/数组中的)都会自动适配大小写变体:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 开启全局枚举大小写不敏感解析 mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); return mapper; } }
此方案无需修改枚举或实体类代码,一劳永逸。
2. 给集合字段指定自定义反序列化器
若不想全局修改,可针对特定集合字段添加注解,使用自定义反序列化器处理大小写兼容:
首先定义通用枚举集合反序列化器:
public class CaseInsensitiveEnumListDeserializer<T extends Enum<T>> extends JsonDeserializer<List<T>> { private final Class<T> enumClass; public CaseInsensitiveEnumListDeserializer(Class<T> enumClass) { this.enumClass = enumClass; } @Override public List<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); List<T> result = new ArrayList<>(); if (node.isArray()) { for (JsonNode element : node) { // 统一转大写匹配枚举,也可根据需求转小写 String value = element.asText().toUpperCase(); result.add(Enum.valueOf(enumClass, value)); } } return result; } }
然后在Bbb记录的集合字段上应用:
public record Bbb( @JsonDeserialize(using = CaseInsensitiveEnumListDeserializer.class, contentAs = FooBarEnum.class) List<FooBarEnum> fooBarList ) {}
3. 给枚举类添加@JsonCreator方法
在枚举类中手动实现大小写兼容的实例创建逻辑,Jackson反序列化单个或集合中的枚举时都会调用该方法:
public enum FooBarEnum { FOO, BAR; @JsonCreator public static FooBarEnum fromString(String value) { if (value == null) { return null; } // 忽略大小写匹配枚举实例 return FooBarEnum.valueOf(value.trim().toUpperCase()); } }
这种方式无需修改全局配置,也不需要给集合字段加额外注解,枚举自身即可兼容大小写。
验证
测试Bbb反序列化时,无论服务端返回["FOO","bar"]还是["foo","BAR"],都能正常解析为对应的枚举列表,不会抛出反序列化异常。
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

