Jackson反序列化枚举报错:存在构造器仍无法创建UserTypeEnum实例
解决Jackson枚举反序列化问题
你遇到的问题是因为@JsonValue仅负责序列化(将枚举转为JSON的整数),但Jackson默认不会用这个值反向完成反序列化——枚举的反序列化逻辑默认是匹配枚举名称或ordinal值,而非你自定义的type字段。另外,枚举的构造器是私有的,Jackson无法直接通过构造器创建枚举实例(枚举实例是预定义的单例,不能通过new生成)。
下面是两种简单可行的解决方案:
方案一:添加@JsonCreator静态工厂方法
在UserTypeEnum中添加一个静态方法,根据传入的type值匹配对应的枚举实例,并标注@JsonCreator注解,告诉Jackson用这个方法完成反序列化:
public enum UserTypeEnum implements EnumConverter { USER(1), USERS_GROUP(2); private final int type; UserTypeEnum(int type) { this.type = type; } @Override @JsonValue public int getType() { return type; } // 添加这个静态方法 @JsonCreator public static UserTypeEnum fromType(int type) { for (UserTypeEnum enumVal : UserTypeEnum.values()) { if (enumVal.getType() == type) { return enumVal; } } // 可根据需求返回null或抛出异常 throw new IllegalArgumentException("无效的UserTypeEnum类型: " + type); } }
这个方法会在Jackson反序列化时被调用,传入JSON中的数字值,返回对应的枚举实例。
方案二:全局配置枚举反序列化规则(适用于多个枚举实现EnumConverter的场景)
如果你的项目中有多个枚举实现了EnumConverter接口,可以自定义一个通用的反序列化器,避免每个枚举都写重复的工厂方法:
- 自定义反序列化器:
public class EnumConverterDeserializer extends StdDeserializer<EnumConverter> { protected EnumConverterDeserializer() { super(EnumConverter.class); } @Override public EnumConverter deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { int type = p.getIntValue(); Class<? extends EnumConverter> enumClass = (Class<? extends EnumConverter>) ctxt.getContextualType().getRawClass(); for (EnumConverter enumVal : enumClass.getEnumConstants()) { if (enumVal.getType() == type) { return enumVal; } } throw ctxt.weirdNumberException(type, enumClass, "无效的枚举类型值"); } }
- 注册到ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(EnumConverter.class, new EnumConverterDeserializer()); objectMapper.registerModule(module);
这样所有实现EnumConverter的枚举,都能自动根据getType()的返回值完成反序列化。
内容的提问来源于stack exchange,提问作者user16076953
相关产品推荐
相关产品推荐

