1

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

4

0 に答える 0