我使用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
我错过了什么?
您可以自定义任何属性的反序列化。
使用将要处理的属性的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;
}
}
我是这样做的:
// Your JSON
{"event":"forgot password"}
// Your class to map
public class LoggingDto {
@JsonProperty(value = "event")
private FooEnum logType;
}
//Your enum
public enum FooEnum {
DATA_LOG ("Dummy 1"),
DATA2_LOG ("Dummy 2"),
DATA3_LOG ("forgot password"),
DATA4_LOG ("Dummy 4"),
DATA5_LOG ("Dummy 5"),
UNKNOWN ("");
private String fullName;
FooEnum(String fullName) {
this.fullName = fullName;
}
public String getFullName() {
return fullName;
}
@JsonCreator
public static FooEnum getLogTypeFromFullName(String fullName) {
for (FooEnum logType : FooEnum.values()) {
if (logType.fullName.equals(fullName)) {
return logType;
}
}
return UNKNOWN;
}
}
因此,类LoggingDto的属性“logType”的值将是DATA3_LOG
注意,在2015年6月的这次提交(Jackson 2.6.2及以上版本)中,你现在可以简单地写:
public enum Event {
@JsonProperty("forgot password")
FORGOT_PASSWORD;
}
行为记录在这里:https://fasterxml.github.io/jackson-annotations/javadoc/2.11/com/fasterxml/jackson/annotation/JsonProperty.html
从Jackson 2.6开始,这个注释也可以用来改变Enum的序列化,如下所示:
public enum MyEnum {
@JsonProperty THE_FIRST_VALUE(“theFirstValue”),
another_value @JsonProperty(“another_value”);
}
作为使用JsonValue注释的替代方法。
我发现了一个非常好的和简洁的解决方案,特别是当您不能修改枚举类时,就像在我的例子中一样。然后,您应该提供一个启用了特定特性的自定义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