jackson-databind
jackson-databind copied to clipboard
Need a Feature like "READ_ENUM_KEYS_USING_INDEX"
With #2129 and jackson 2.10.0 a new Feature WRITE_ENUM_KEYS_USING_INDEX was introduced.
So we now can write an enum used in a map as key as number/enum index. (This is usefull as the other side is written in C and works indexed based, ...) That works fine. See Example below.
Problem: the json generated by jackson this way cannot be deserialized.
This unbalanced situation - jackson cannot read his own json - was described in #1877
Seems jackson needs a feature like "READ_ENUM_KEYS_USING_INDEX" (suggestion regarding #2129 )
Sample Code explaining the situation:
package jackson_enum_as_key;
import com.fasterxml.jackson.databind.*;
import java.io.IOException;
import java.util.*;
public class Main {
public enum Type {
ANY,
OTHER
}
public static class Container {
private Type simpleType;
private Map<Type, String> map;
public Type getSimpleType() {
return simpleType;
}
public void setSimpleType(Type simpleType) {
this.simpleType= simpleType;
}
public Map<Type, String> getMap() {
return map;
}
public void setMap(Map<Type, String> map) {
this.map = map;
}
}
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, true);
objectMapper.configure(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX, true);
Map<Type, String> map = new HashMap<>();
map.put(Type.OTHER, "hello world");
Container container = new Container();
container.setSimpleType(Type.ANY);
container.setMap(map);
String json = objectMapper.writeValueAsString(container);
System.out.println(json);
objectMapper.readValue(json, Container.class);
}
}
Problem:
/opt/java/jdk1.8.0_151/bin/java jackson_enum_as_key.Main
{"simpleType":0,"map":{"1":"hello world"}}
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize Map key of type `jackson_enum_as_key.Main$Type` from String "1": not a valid representation, problem: (com.fasterxml.jackson.databind.exc.InvalidFormatException) Cannot deserialize Map key of type `jackson_enum_as_key.Main$Type` from String "1": not one of the values accepted for Enum class: [OTHER, ANY]
at [Source: (String)"{"simpleType":0,"map":{"1":"hello world"}}"; line: 1, column: 24] (through reference chain: jackson_enum_as_key.Main$Container["map"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.weirdKeyException(DeserializationContext.java:1653)
at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdKey(DeserializationContext.java:886)
at com.fasterxml.jackson.databind.deser.std.StdKeyDeserializer.deserializeKey(StdKeyDeserializer.java:138)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBind(MapDeserializer.java:449)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:367)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
at jackson_enum_as_key.Main.main(Main.java:51)
Process finished with exit code 1
Support could be added via new EnumFeature mechanism, but implementation still needed.
I probably won't have time to tackle this but could help anyone who has time and interest.
is there anyone working on this? I got some time off so I will make a PR in a day or two
@JooHyukKim I don't think anyone is working on this, so go ahead! It could make it into 2.15; let me know if you need help with EnumFeature (you should be able to see how existing JsonNodeFeature is used, defined -- need to add the first enum value for EnumFeature but otherwise it should be easily accessible).
@cowtowncoder thanks for your reply.
I actually did make a Pull Request on this yesterday.
I missed out EnumFeature on my PR, I thought READ_ENUM_KEYS_USING_INDEX config belonged to DeserializationFeature class?
It'd be nice if you could help me out on understanding how EnumFeature relates here a little bit? 🥹