Bagaimana cara memberitahu Jackson untuk tidak memasukkan informasi jenis koleksi?

Saya mengalami "masalah deserialisasi polimorfik", jadi saya mengonfigurasi jackson untuk menambahkan informasi tipe untuk kelas non-beton sebagai properti sebagai berikut:

ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
        .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
        .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
        .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
        .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
        .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE))
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_CONCRETE_AND_ARRAYS, "__class__")

Ini berfungsi dengan baik, tetapi untuk contoh koleksi (Daftar misalnya) ia membuat array dua elemen dengan posisi pertama memegang string dengan informasi tipe koleksi (java.util.ArrayList).

Hal ini mempengaruhi struktur json yang diharapkan klien (Javascript), karena di mana ia mengharapkan sebuah array, sekarang ada sebuah array dengan array lain di dalamnya pada posisi kedua.

Saya berharap Jackson memasukkan informasi tipe hanya untuk non-koleksi, bukan tipe konkret, karena kerangka itu sendiri tidak memerlukan tipe implementasi koleksi untuk membatalkan serialisasi properti koleksi dengan benar.

Apakah ini mungkin dengan cara yang dapat dikonfigurasi?


person MV Gagliotti    schedule 11.09.2014    source sumber


Jawaban (1)


Anda dapat membuat versi khusus ObjectMapper.DefaultTypeResolverBuilder dan mengganti metode useForType().

Berikut implementasi metode default:

    public boolean useForType(JavaType t)
    {
        switch (_appliesFor) {
        case NON_CONCRETE_AND_ARRAYS:
            while (t.isArrayType()) {
                t = t.getContentType();
            }
            // fall through
        case OBJECT_AND_NON_CONCRETE:
            return (t.getRawClass() == Object.class) || !t.isConcrete();
        case NON_FINAL:
            while (t.isArrayType()) {
                t = t.getContentType();
            }
            return !t.isFinal(); // includes Object.class
        default:
        //case JAVA_LANG_OBJECT:
            return (t.getRawClass() == Object.class);
        }
    }

Di versi Anda, tambahkan saja prasyarat ini

if (t.isCollectionLikeType()) {
    return false;
}

untuk memberitahu Jackson untuk melewati tipe mirip Koleksi untuk memasukkan informasi tipe.

Dan atur TypeResolverBuilder baru Anda dengan ObjectMapper.setDefaultTyping(myCustomTyper);

person scip    schedule 24.04.2015