Jackson deserializing into Map with an Enum Key, POJO Value

那年仲夏 提交于 2019-12-08 18:33:20

问题


I am trying to deserialize JSON into a Java POJO using Jackson. Without giving away confidential information, here is an example stack trace when ObjectMapper's deserialization fails:

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

My JSON looks like this:

"foo": {
    "coins": null,
    ...
}

And the class I want to deserialize into has this field:

private Map<MyEnum, MyPojo> foo;

And my enum type looks like this:

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

I do realize that I am trying to deserialize a null value. But I believe this should still work: the result of the deserialization should be equivalent to having a Map with foo.put(MyEnum.COINS, null), which is indeed a valid Java instruction. Help is much appreciated, thanks in advance.


回答1:


In addition to one good solution presented (factory method), there are 2 other ways:

  • If 'MyEnum.toString()' would return "coins", you can make Jackson use "toString()" over "name()"with ObjectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
  • You could add some other method to return id to use, and mark that method with @JsonValue annotation (you can actually use that on toString() as well, instead of enabling above feature) -- if that annotation exists, value returned by that method is used as the id.



回答2:


GRR! Figured it out.

Solution for me was to create a static method, annotated with @JsonCreator, in my enum that creates an instance of the enum, based on a String parameter. It looked like this:

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



回答3:


Provide a static factory method in your enumeration class that constructs enum by string and annotate it with @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);
}


来源:https://stackoverflow.com/questions/13406568/jackson-deserializing-into-map-with-an-enum-key-pojo-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!