Jackson 使用枚举键、POJO 值反序列化为 Map

Posted

技术标签:

【中文标题】Jackson 使用枚举键、POJO 值反序列化为 Map【英文标题】:Jackson deserializing into Map with an Enum Key, POJO Value 【发布时间】:2012-11-04 14:05:05 【问题描述】:

我正在尝试使用 Jackson 将 JSON 反序列化为 Java POJO。在不泄露机密信息的情况下,以下是 ObjectMapper 反序列化失败时的示例堆栈跟踪:

org.codehaus.jackson.map.JsonMappingException: Can not construct Map key of type com.example.MyEnum from String "coins": not a valid representation: Can not construct Map key of type com.example.MyEnum from String "coins": not one of values for Enum class

我的 JSON 如下所示:

"foo": 
    "coins": null,
    ...

我想反序列化的类有这个字段:

private Map<MyEnum, MyPojo> foo;

我的枚举类型如下所示:

public enum MyEnum 
    COINS("coins"),
    ...

我确实意识到我正在尝试反序列化一个空值。但我相信这仍然有效:反序列化的结果应该等同于拥有一个带有foo.put(MyEnum.COINS, null) 的 Map,这确实是一条有效的 Java 指令。非常感谢您的帮助,在此先感谢。

【问题讨论】:

在你的枚举类中提供一个静态工厂方法,通过字符串构造枚举 问题的原因是默认情况下杰克逊使用enum.name() 作为 id - 在这种情况下,名称是“COINS”,而不是小写的“coins”。正如答案所指出的那样,有很多方法可以解决这个问题。 【参考方案1】:

除了提出的一种好的解决方案(工厂方法)之外,还有另外两种方法:

如果“MyEnum.toString()”会返回“coins”,您可以让 Jackson 使用“toString()”而不是“name()”和 ObjectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) 您可以添加一些其他方法来返回要使用的 id,并使用 @JsonValue 注释标记该方法(实际上您也可以在 toString() 上使用它,而不是启用上述功能)——如果该注释存在,该方法返回的值用作 id。

【讨论】:

【参考方案2】:

GRR!想通了。

我的解决方案是在我的枚举中创建一个带有 @JsonCreator 注释的静态方法,该方法基于字符串参数创建枚举的实例。它看起来像这样:

@JsonCreator
public static MyEnum create(String str) 
    // code to return an enum based on the String parameter

【讨论】:

【参考方案3】:

在你的枚举类中提供一个静态工厂方法,通过字符串构造枚举并用@JsonCreator注解:

@JsonCreator
public static MyEnum fromValue(String v) 
    for (MyEnum myEnum : values()) 
        if (myEnum.text.equals(v)) 
            return myEnum;
        
    
    throw new IllegalArgumentException("invalid string value passed: " + v);

【讨论】:

return valueOf(v); 不够吗? @StefanHendriks,如果作者通过枚举名称(硬币)重建枚举就足够了,但问题说它是使用枚举自定义字段(硬币)反序列化

以上是关于Jackson 使用枚举键、POJO 值反序列化为 Map的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jackson XmlMapper 将 XML 反序列化为 POJO

使用 Jackson 将 JSON 反序列化为 ArrayList<POJO>

Java Jackson将空字段反序列化为POJO中的默认空列表

将 HTTP 请求数据转换为枚举时捕获异常

Java Jackson将JSON序列化为HashTable

Jackson:将枚举值序列化和反序列化为整数