Java Jackson使用枚举键POJO值反序列化到映射中

Java Jackson使用枚举键POJO值反序列化到映射中,java,json,serialization,jackson,jsonserializer,Java,Json,Serialization,Jackson,Jsonserializer,我正在尝试使用Jackson将JSON反序列化为JavaPOJO。在不泄露机密信息的情况下,以下是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 ke

我正在尝试使用Jackson将JSON反序列化为JavaPOJO。在不泄露机密信息的情况下,以下是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,
    ...
}
public enum MyEnum {
    COINS("coins"),
    ...
}
@JsonCreator
public static MyEnum create(String str) {
    // code to return an enum based on the String parameter
}
我要反序列化到的类有以下字段:

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

GRR!我明白了

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

"foo": {
    "coins": null,
    ...
}
public enum MyEnum {
    COINS("coins"),
    ...
}
@JsonCreator
public static MyEnum create(String str) {
    // code to return an enum based on the String parameter
}

在枚举类中提供一个静态工厂方法,该方法通过字符串构造枚举,并使用@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);
}

除了一个好的解决方案(工厂法)外,还有两种其他方法:

  • 如果“MyEnum.toString()”将返回“coins”,则可以使用
    ObjectMapper.enable(反序列化功能。使用\u TO \u字符串读取\u枚举)
  • 您可以添加一些其他方法来返回要使用的id,并用
    @JsonValue
    注释标记该方法(您实际上也可以在
    toString()
    上使用该方法,而不是启用上述功能)——如果该注释存在,则该方法返回的值将用作id

在枚举类中提供一个按字符串构造枚举的静态工厂方法,问题的原因是默认情况下Jackson使用
enum.name()
作为id——在这种情况下,名称是“COINS”,而不是小写的“COINS”。正如答案所指出的,有很多方法可以解决这个问题。
是否会返回(v)的值是否足够?@StefanHendriks,若作者通过枚举名(硬币)重建枚举就足够了,但问题是,它是使用枚举自定义字段(硬币)反序列化的