13

リストプロパティを持つオブジェクトがあるとしましょう:

public class Citizen {
    name
    List<Tickets> tickets
    List<Fines> fines
}

注釈を使用して、リストの汎用カスタム デシリアライザーを定義したいと思います。

public class Citizen {
    ...
    @JsonDeserializer(MyListDeserializer<Tickets>) // <-- generic deserializer
    public void setTickets(List<Tickets> tickets) {
        this.tickets = tickets;
    }

    @JsonDeserializer(MyListDeserializer<Fines>) // <-- how can I do that? 
    public void setFines(List<Fines> fines) {
        this.fines = fines;
    }
}

「ジェネリック」デシリアライザーを作成する方法を探しています。これは、 JSON を Jackson でさまざまなタイプのマップにマッピングするための ContextualDeserializer と同様に、両方のタイプのリストをデシリアライズできるものです。

最終的な目的は、MyListDeserializer空の文字列""を空のリストとして逆シリアル化するカスタム逆シリアル化ロジックを実装することですが、空の文字列だけでなく、一般的なアプローチについて知りたいです。

4

1 に答える 1

17

リストの要素をアノテーションのcontentUsing属性でデシリアライズするデシリアライザ クラスを指定できます。@JsonDeserializer

public class Citizen {
    ...
    @JsonDeserializer(contentUsing=MyListDeserializer.class) 
    public void setTickets(List<Tickets> tickets) {
        this.tickets = tickets;
    }
}

デシリアライザーを拡張JsonDeserializer<BaseClass>し、具象クラスの実際の型を格納する BaseClass に属性を持たせます。

abstract class BaseTickets {
    String ticketType;
    public String getTicketType()
}

public class MyListDeserializer extends JsonDeserializer<BaseTickets> {

    @Override
    public BaseTickets deserialize(JsonParser jsonParser, DeserializationContext arg1) throws IOException, JsonProcessingException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        Iterator<JsonNode> elements = node.getElements();
        for (; elements.hasNext();) {
            String type = (String) elements.next().get("ticketType");

            if (type.equals()){
               //create concrete type here
            }
        }
     }

または、共通の基本クラスを持たないすべての List タイプに対して単一のデシリアライザーが必要な場合は、using属性を使用して、 MyListDeserializerextendを持っていJsonDeserialize<Object>ます。リスト要素の型を決定するには、汎用デシリアライザーで使用できる型情報をリストに追加するカスタム シリアライザーを作成する必要があります。

public class Citizen {
    ...
    @JsonDeserializer(using=MyListDeserializer.class)
    @JsonSerializer(using=MyListSerializer.class) 
    public void setTickets(List<Tickets> tickets) {
        this.tickets = tickets;
    }
}

public class MyListSerializer extends JsonSerializer<Object> {

    @Override
    public void serialize(Object list, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        @SuppressWarnings("rawtypes")
        jgen.writeStartObject();
        String type = getListType(list);
        jgen.writeStringField("listType", type);
        jgen.writeObjectField("list", list)
    }
}
于 2012-10-17T15:18:28.513 に答える