我无法让杰克逊尊重我的自定义JsonDeserializer。情况是,我有一个类MyClass
,其中包含另一个类OtherClass
的列表,这是我无法控制的(因此我无法对其进行注释)。此OtherClass
类是具有多个实现的接口。我不关心原OtherClass
是什么,我希望它们始终反序列化为BasicOtherClass
。
这就是我所拥有的:
@Getter
public class MyClass {
@JsonProperty("otherclasses")
@JsonSerialize(contentUsing=OtherClassSerializer.class)
@JsonDeserialize(contentUsing=OtherClassDeserializer.class)
private List<OtherClass> otherClasses;
public MyClass(
@JsonProperty("otherclasses")
@JsonDeserialize(contentUsing=OtherClassDeserializer.class)
List<OtherClass> otherClasses) {
this.otherClass = otherClass;
}
}
public static class OtherClassSerializer extends JsonSerializer<OtherClass> {
@Override
public void serialize(OtherClass otherClass, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
gen.writeStartObject();
gen.writeStringField("name", otherClass.getName());
gen.writeStringField("value", otherClass.getValue());
gen.writeEndObject();
}
/** This method is required when default typing is enabled */
@Override
public void serializeWithType(
OtherClass otherClass, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer)
throws JsonProcessingException, IOException {
typeSer.writeTypePrefixForScalar(value, gen, OtherClass.class);
serialize(value, gen, serializers);
typeSer.writeTypeSuffixForScalar(value, gen);
}
}
public static class OtherClassDeserializer extends JsonDeserializer<Header> {
@Override
public Header deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
if (p.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IllegalStateException("Failed to parse OtherClass from json");
}
String name = null;
String value = null;
while (p.nextToken() != JsonToken.END_OBJECT) {
String key = p.getText();
p.nextToken();
String val = p.getText();
if (key.equals("name")) {
name = val;
} else if (key.equals("value")) {
value = val;
}
}
return new BasicOtherClass(name, value);
}
}
这就是我想要的工作:
ObjectMapper mapper = new ObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
OtherClass otherClass = new BufferedOtherClass("name value");
MyClass myClass = new MyClass(Lists.newArrayList(otherClass));
String json = mapper.writeValueAsString(myClass);
// json == ["com.bschlenk.MyClass", {"otherclass": ["java.util.ArrayList", [["com.other.OtherClass", {"name": "name", "value", "value"}]]]}]
但是当我尝试将json读回MyClass
时,它失败了:
MyClass parsed = mapper.readValue(json, MyClass.class);
// com.fasterxml.jackson.databind.JsonMappingException:
// Can not construct instance of org.apache.http.Header, problem:
// abstract types either need to be mapped to concrete types,
// have custom deserializer,
// or be instantiated with additional type information
当我没有启用类型信息时,这是有效的。但是,它是序列化MyClass
的其他代码,我无法控制,并且它具有类型信息。
我想做的甚至可能吗?为什么mapper.readValue
不使用我的自定义JsonDeserializer
课程?这是设计吗?