我使用JAVA 1.6和Jackson 1.9.9,我有一个enum
public enum Event {
FORGOT_PASSWORD("forgot password");
private final String value;
private Event(final String description) {
this.value = description;
}
@JsonValue
final String value() {
return this.value;
}
}
我已经添加了一个@JsonValue,这似乎做的工作,它序列化对象:
{"event":"forgot password"}
但当我尝试反序列化时,我得到
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.globalrelay.gas.appsjson.authportal.Event from String value 'forgot password': value not one of declared Enum instance names
我错过了什么?
我发现了一个非常好的和简洁的解决方案,特别是当您不能修改枚举类时,就像在我的例子中一样。然后,您应该提供一个启用了特定特性的自定义ObjectMapper。这些特性从Jackson 1.6开始就可以使用了。所以你只需要在你的enum中写入toString()方法。
public class CustomObjectMapper extends ObjectMapper {
@PostConstruct
public void customConfiguration() {
// Uses Enum.toString() for serialization of an Enum
this.enable(WRITE_ENUMS_USING_TO_STRING);
// Uses Enum.toString() for deserialization of an Enum
this.enable(READ_ENUMS_USING_TO_STRING);
}
}
还有更多与枚举相关的特性可用,请参见这里:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
下面是另一个使用字符串值而不是映射的例子。
public enum Operator {
EQUAL(new String[]{"=","==","==="}),
NOT_EQUAL(new String[]{"!=","<>"}),
LESS_THAN(new String[]{"<"}),
LESS_THAN_EQUAL(new String[]{"<="}),
GREATER_THAN(new String[]{">"}),
GREATER_THAN_EQUAL(new String[]{">="}),
EXISTS(new String[]{"not null", "exists"}),
NOT_EXISTS(new String[]{"is null", "not exists"}),
MATCH(new String[]{"match"});
private String[] value;
Operator(String[] value) {
this.value = value;
}
@JsonValue
public String toStringOperator(){
return value[0];
}
@JsonCreator
public static Operator fromStringOperator(String stringOperator) {
if(stringOperator != null) {
for(Operator operator : Operator.values()) {
for(String operatorString : operator.value) {
if (stringOperator.equalsIgnoreCase(operatorString)) {
return operator;
}
}
}
}
return null;
}
}
您可以自定义任何属性的反序列化。
使用将要处理的属性的annotationJsonDeserialize (import com.fasterxml.jackson.databin .annotation. jsondeserialize)声明反序列化类。如果这是一个Enum:
@JsonDeserialize(using = MyEnumDeserialize.class)
private MyEnum myEnum;
通过这种方式,您的类将被用于反序列化属性。这是一个完整的例子:
public class MyEnumDeserialize extends JsonDeserializer<MyEnum> {
@Override
public MyEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
MyEnum type = null;
try{
if(node.get("attr") != null){
type = MyEnum.get(Long.parseLong(node.get("attr").asText()));
if (type != null) {
return type;
}
}
}catch(Exception e){
type = null;
}
return type;
}
}