4

I'm trying to map this JSON :

{"ref":"code","type":"desc"}

With those JAX-RS classes :

public class Sorting {
    public String ref;
    public SortingType type;
}
@XmlType
@XmlEnum
public enum SortingType {
    @XmlEnumValue("asc")
    ASCENDING,
    @XmlEnumValue("desc")
    DESCENDING;
}

With this I have that error (I'm using JBoss EAP 6.2):

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.mycompany.myproject.SortingType from String value 'desc': value not one of declared Enum instance names
 at [Source: org.apache.catalina.connector.CoyoteInputStream@76e7449; line: 1, column: 47] (through reference chain: com.mycompany.myproject.Sorting["type"])
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)

By looking at the documentation, I've also tried that definition without any success:

@XmlType
@XmlEnum
public enum SortingType {
    @XmlEnumValue("asc")
    ASCENDING("asc"),
    @XmlEnumValue("desc")
    DESCENDING("desc");

    private String code;

    SortingType(String code) {
    this.code = code;
    }
}
Anthony O.
  • 22,041
  • 18
  • 107
  • 163

2 Answers2

0

I used that ugly code waiting a better answer:

@XmlEnum
public enum SortingType {
    @XmlEnumValue("asc")
    ASCENDING,
    @XmlEnumValue("desc")
    DESCENDING;

    private static Map<String, SortingType> sortingTypeByValue = new HashMap<>();
    private static Map<SortingType, String> valueBySortingType = new HashMap<>();
    static {
        SortingType[] enumConstants = SortingType.class.getEnumConstants();
        for (SortingType sortingType : enumConstants) {
            try {
                String value = SortingType.class.getField(sortingType.name()).getAnnotation(XmlEnumValue.class).value();
                sortingTypeByValue.put(value, sortingType);
                valueBySortingType.put(sortingType, value);
            } catch (NoSuchFieldException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    @JsonCreator
    public static SortingType create(String value) {
        return sortingTypeByValue.get(value);
    }

    @JsonValue
    public String getValue() {
        return valueBySortingType.get(this);
    }
}
Anthony O.
  • 22,041
  • 18
  • 107
  • 163
0

Old question, but I'll give this a shot... I'm not using XML annotated types, but I did have the same issue with converting enumerations to JSON.

In my webapp, I already had a custom objectMapper to handle my use of JodaTime objects, so I added the serialization/deserialization feature in a PostConstruct method.

import javax.annotation.PostConstruct;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.joda.JodaModule;

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper>{

    final ObjectMapper mapper = new ObjectMapper();

    public ObjectMapperContextResolver() {
        mapper.registerModule(new JodaModule());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }

    @PostConstruct
    public void customConfiguration(){
        mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
        mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
    }
}

Source: http://fasterxml.github.io/jackson-databind/javadoc/2.3.0/com/fasterxml/jackson/databind/SerializationFeature.html

JHarnach
  • 3,944
  • 7
  • 43
  • 48
  • And with this, my original `enum` will be correctly mapped from JSON `{"ref":"code","type":"desc"}` ? – Anthony O. Apr 29 '15 at 08:59
  • @AnthonyO. It should, the code sample above allowed me to pass json around and have it correctly mapped to an enum. – JHarnach Apr 29 '15 at 18:06