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.
By default, Jackson will use the Enum name to deserialize from JSON. If we want Jackson to case-insensitively deserialize from JSON by the Enum name, we need to customize the ObjectMapper to enable the ACCEPT_CASE_INSENSITIVE_ENUMS feature.
1.12 Serialization of Enum Constants To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java. lang. Enum.
Just like Java objects, we can serialize and deserialize Java Map by using Jackson. We can easily serialize and deserialize Map<Object, Object>, Map<Object, String>, and Map<String, String> to or from JSON-formatted strings by using Jackson.
JSON has no enum type. The two ways of modeling an enum would be: An array, as you have currently. The array values are the elements, and the element identifiers would be represented by the array indexes of the values.
In addition to one good solution presented (factory method), there are 2 other ways:
ObjectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
@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.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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With