ジャクソンにカスタム 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
クラスを使用しないのはなぜですか? これは設計によるものですか?