Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@JsonValue on an enum field, when this enum used as map key

public enum ClusterType {
    TEMPERATURE("0402"),
    HUMIDITY("0405"),
    ENERGY_DETAILS("0702"),
    SMART_SOCKET_STATUS("0006"),
    ALARMED("0500");

    private String value = null;

    ClusterType(String byteStr) {
        this.value = byteStr;
    }

    @JsonCreator
    public static ClusterType fromValue(final String val){
        return (ClusterType) CollectionUtils.find(Arrays.asList(ClusterType.values()), new Predicate() {
            public boolean evaluate(Object object) {
                ClusterType candidate = (ClusterType) object;
                return StringUtils.equals(candidate.value, val);
            }
        });
    }

    @JsonValue
    public String getValue(){
        return value;
    }

    public byte[] get() {
        return ByteUtils.hexStringToByteArray(value);
    }

    public boolean equals(String cluster) {
        return StringUtils.equals(cluster, value);
    }
}

I have the above enumeration with

@JsonValue public String getValue(){ return value; }

part and a sample test class like...

public class Foo {

public static void main(String[] args) {
    try {
        ObjectMapper objectMapper = new ObjectMapper();

        ClusterType []arrayRep = new ClusterType[]{ClusterType.ALARMED, ClusterType.TEMPERATURE};

        Map<String, ClusterType>  mapRepAsValue = new HashMap<>();
        mapRepAsValue.put("1", ClusterType.ALARMED);
        mapRepAsValue.put("2", ClusterType.TEMPERATURE);

        Map<ClusterType, String>  mapRepAsKey = new HashMap<>();
        mapRepAsKey.put(ClusterType.ALARMED, "1");
        mapRepAsKey.put(ClusterType.TEMPERATURE, "2");

        System.out.println(objectMapper.writeValueAsString(arrayRep));
        System.out.println(objectMapper.writeValueAsString(mapRepAsValue));
        System.out.println(objectMapper.writeValueAsString(mapRepAsKey));

    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
} }

This test class prints out

["0500","0402"]
{"2":"0402","1":"0500"}
{"TEMPERATURE":"2","ALARMED":"1"}

@JsonValue is not working when used on an enum field which is a key of map.

Is there a way to use this enum as key when serializing maps?

Thanks.

like image 735
acemrek Avatar asked Feb 25 '14 18:02

acemrek


People also ask

Can I use enum as map key?

In HashMap, we can use Enum as well as any other object as a key.

Can enum be used as a key in map Java?

In HashMap, there is no constraint. You can use Enum as well as any other Object as key.

How do you deserialize an enum in Java?

The @JsonValue annotation is one of the annotations which we can use for both serializing and deserializing enums. Enum values are constants, and due to this, @JsonValue annotation can be used for both. First we simply add the getter method to our Distance. java by using the @JsonValue annotation.


Video Answer


1 Answers

Actually, I think this is just a feature that hasn't been added, as per:

https://github.com/FasterXML/jackson-databind/issues/47

so whereas @JsonValue works fine for Enums with respect to deserialization, it does not yet work for serialization. Project is always open for contributions, if anyone has time to tackle this -- it should not be big undertaking.

like image 98
StaxMan Avatar answered Sep 25 '22 17:09

StaxMan