Jackson Abaikan Properti di Marshalling

1. Ikhtisar

Tutorial ini akan menunjukkan cara mengabaikan bidang tertentu saat membuat serial objek ke JSON menggunakan Jackson 2.x.

Ini sangat berguna ketika default Jackson tidak cukup dan kita perlu mengontrol dengan tepat apa yang diserialkan ke JSON - dan ada beberapa cara untuk mengabaikan properti.

Jika Anda ingin menggali lebih dalam dan mempelajari hal-hal keren lainnya yang dapat Anda lakukan dengan Jackson - lanjutkan ke tutorial utama Jackson.

2. Abaikan Bidang di Tingkat Kelas

Kita bisa mengabaikan bidang tertentu di tingkat kelas, menggunakan anotasi @ JsonIgnoreProperties dan menentukan bidang dengan nama :

@JsonIgnoreProperties(value = { "intValue" }) public class MyDto { private String stringValue; private int intValue; private boolean booleanValue; public MyDto() { super(); } // standard setters and getters are not shown }

Sekarang kita dapat menguji bahwa, setelah objek ditulis ke JSON, kolom tersebut memang bukan bagian dari output:

@Test public void givenFieldIsIgnoredByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); MyDto dtoObject = new MyDto(); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); }

3. Abaikan Bidang di Tingkat Bidang

Kita juga bisa mengabaikan bidang secara langsung melalui anotasi @ JsonIgnore langsung di bidang :

public class MyDto { private String stringValue; @JsonIgnore private int intValue; private boolean booleanValue; public MyDto() { super(); } // standard setters and getters are not shown }

Sekarang kita dapat menguji bahwa bidang intValue memang bukan bagian dari keluaran JSON serial:

@Test public void givenFieldIsIgnoredDirectly_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); MyDto dtoObject = new MyDto(); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); }

4. Abaikan Semua Kolom menurut Jenis

Akhirnya, kita bisa mengabaikan semua bidang dari tipe yang ditentukan, menggunakan anotasi @ JsonIgnoreType . Jika kita mengontrol tipenya, maka kita dapat membuat anotasi kelas secara langsung:

@JsonIgnoreType public class SomeType { ... }

Lebih sering daripada tidak, bagaimanapun, kita tidak memiliki kendali atas kelas itu sendiri; dalam hal ini, kita dapat memanfaatkan Jackson mixin dengan baik .

Pertama, kita mendefinisikan MixIn untuk tipe yang ingin kita abaikan, dan beri anotasi dengan @JsonIgnoreType sebagai gantinya:

@JsonIgnoreType public class MyMixInForIgnoreType {}

Kemudian kita mendaftarkan mixin itu untuk mengganti (dan mengabaikan) semua tipe String [] selama marshaling:

mapper.addMixInAnnotations(String[].class, MyMixInForIgnoreType.class);

Pada titik ini, semua larik String akan diabaikan alih-alih disusun ke JSON:

@Test public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(String[].class, MyMixInForIgnoreType.class); MyDtoWithSpecialField dtoObject = new MyDtoWithSpecialField(); dtoObject.setBooleanValue(true); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, containsString("intValue")); assertThat(dtoAsString, containsString("booleanValue")); assertThat(dtoAsString, not(containsString("stringValue"))); }

dan inilah DTO kami:

public class MyDtoWithSpecialField { private String[] stringValue; private int intValue; private boolean booleanValue; }

Catatan: Sejak versi 2.5 - tampaknya kita tidak dapat menggunakan metode ini untuk mengabaikan tipe data primitif, tetapi kita dapat menggunakannya untuk tipe dan array data kustom.

5. Abaikan Fields Menggunakan Filter

Terakhir, kami juga dapat menggunakan filter untuk mengabaikan bidang tertentu di Jackson. Pertama, kita perlu mendefinisikan filter pada objek Java:

@JsonFilter("myFilter") public class MyDtoWithFilter { ... }

Kemudian, kami menentukan filter sederhana yang akan mengabaikan bidang intValue :

SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter .serializeAllExcept("intValue"); FilterProvider filters = new SimpleFilterProvider() .addFilter("myFilter", theFilter);

Sekarang kita dapat membuat serial objek dan memastikan bahwa bidang intValue tidak ada dalam output JSON:

@Test public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter .serializeAllExcept("intValue"); FilterProvider filters = new SimpleFilterProvider() .addFilter("myFilter", theFilter); MyDtoWithFilter dtoObject = new MyDtoWithFilter(); String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); assertThat(dtoAsString, containsString("booleanValue")); assertThat(dtoAsString, containsString("stringValue")); System.out.println(dtoAsString); }

6. Kesimpulan

Artikel tersebut mengilustrasikan cara mengabaikan bidang pada serialisasi - pertama dengan nama, lalu secara langsung, dan terakhir - kami mengabaikan seluruh tipe java dengan MixIns dan kami menggunakan filter untuk lebih mengontrol output.

Penerapan semua contoh dan cuplikan kode ini dapat ditemukan di proyek GitHub saya.