枚举的反序列化不起作用 - Jackson [重复]
Posted
技术标签:
【中文标题】枚举的反序列化不起作用 - Jackson [重复]【英文标题】:Deserialization of Enum does not work - Jackson [duplicate] 【发布时间】:2017-12-01 01:59:41 【问题描述】:我尝试序列化和反序列化枚举。但是杰克逊使用自然枚举顺序值而不是我的。
我使用杰克逊 2.8.9。
我的测试枚举:
public enum SomeEnum
SOME_VAL1(1),
SOME_VAL2(2),
SOME_VAL3(3),
SOME_VAL4(4);
private final Integer code;
@JsonCreator
SomeEnum(@JsonProperty("code") Integer code)
this.code = code;
@JsonValue
public Integer getCode()
return code;
这是我测试失败的完整代码:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class Program
public enum SomeEnum
SOME_VAL1(1),
SOME_VAL2(2),
SOME_VAL3(3),
SOME_VAL4(4);
private final Integer code;
@JsonCreator
SomeEnum(@JsonProperty("code") Integer code)
this.code = code;
@JsonValue
public Integer getCode()
return code;
public static class EnumWrapper
private final SomeEnum someEnumVal;
public EnumWrapper(@JsonProperty("someEnum") SomeEnum someEnumVal)
this.someEnumVal = someEnumVal;
@JsonProperty("someEnum")
public SomeEnum getSomeEnumVal()
return someEnumVal;
public static void main(String[] args) throws IOException
ObjectMapper mapper = new ObjectMapper();
String inputJson = mapper.writeValueAsString(new EnumWrapper(SomeEnum.SOME_VAL3));
EnumWrapper resultEnumWrapper =
mapper.readValue(inputJson, EnumWrapper.class);
if (resultEnumWrapper.getSomeEnumVal() != SomeEnum.SOME_VAL3)
System.out.println(resultEnumWrapper.getSomeEnumVal());
System.out.println(inputJson);
throw new RuntimeException("enum = " + resultEnumWrapper.getSomeEnumVal());
为什么我有这个错误的枚举反序列化?我使用@JsonProperty
。
【问题讨论】:
你不能在枚举定义之外调用枚举构造函数,所以@JsonCreator
是没用的。请尝试使用静态工厂方法。
@shmosel jackson 使用带有帮助反射的构造函数。
不能通过反射或任何其他方式从外部构造枚举实例。
***.com/questions/12468764/…
【参考方案1】:
尝试使用@JsonCreator
公开方法,例如:
@JsonCreator
public static SomeEnum findByCode(final int code)
for (final SomeEnum element : values())
if (element.getCode().equals(code))
return element;
return null;
【讨论】:
它可以工作,但有一些问题。首先,它具有 O(N) 复杂度。其次,我必须为每个 Enum 编写这样的代码。 @Max 不是针对每个枚举,而是针对那些具有引用变量并且需要通过引用值查找的枚举。关于 O(N),您可以对枚举中的所有值进行哈希映射并使用get
。
除非你的枚举有一百万个值,否则没关系。【参考方案2】:
如何使用 Jackson 的面向方法的声明并使用输入字符串定义 setter,这将在内部实例化 enum ?
private SomeEnum someEnum;
public void setSomeEnum(String value )
【讨论】:
以上是关于枚举的反序列化不起作用 - Jackson [重复]的主要内容,如果未能解决你的问题,请参考以下文章
StreamReader 和 JsonTextReader 的反序列化不起作用