Jackson Abaikan Properties pada Marshalling

1. Gambaran keseluruhan

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

Ini sangat berguna apabila default Jackson tidak mencukupi dan kita perlu mengawal dengan tepat apa yang diserahkan kepada JSON - dan terdapat beberapa cara untuk mengabaikan sifat.

Sekiranya anda ingin menggali lebih mendalam dan mengetahui perkara menarik lain yang boleh anda lakukan dengan Jackson - teruskan ke tutorial Jackson utama.

2. Abaikan Padang di Peringkat Kelas

Kita boleh mengabaikan bidang tertentu di peringkat kelas, dengan 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 }

Kita sekarang boleh menguji bahawa, setelah objek ditulis ke JSON, medan itu sebenarnya bukan sebahagian daripada 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 Padang di Tingkat Padang

Kami juga boleh mengabaikan medan secara langsung melalui @ JsonI abaikan anotasi secara langsung di lapangan :

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

Kita sekarang boleh menguji bahawa medan intValue memang bukan sebahagian daripada output JSON bersiri:

@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 Medan mengikut Jenis

Akhirnya, kita boleh mengabaikan semua bidang dari jenis yang ditentukan, menggunakan anotasi @ JsonIgnoreType . Sekiranya kita mengawal jenisnya, maka kita dapat memberi anotasi kelas secara langsung:

@JsonIgnoreType public class SomeType { ... }

Lebih kerap daripada itu, kita tidak mempunyai kawalan kelas itu sendiri; dalam kes ini, kita boleh menggunakan Jackson mixins dengan baik .

Mula-mula, kami menentukan MixIn untuk jenis yang ingin kami abaikan, dan memberi komen dengan @JsonIgnoreType sebagai gantinya:

@JsonIgnoreType public class MyMixInForIgnoreType {}

Kemudian kami mendaftarkan mixin tersebut untuk menggantikan (dan mengabaikan) semua jenis String [] semasa marshaling:

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

Pada ketika ini, semua tatasusunan String akan diabaikan dan bukannya digabungkan 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 - nampaknya kami tidak dapat menggunakan kaedah ini untuk mengabaikan jenis data primitif, tetapi kami dapat menggunakannya untuk jenis dan susunan data tersuai.

5. Abaikan Medan Menggunakan Penapis

Akhirnya, kita juga dapat menggunakan penapis untuk mengabaikan bidang tertentu di Jackson. Pertama, kita perlu menentukan penapis pada objek Java:

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

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

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

Sekarang kita dapat membuat siri objek dan memastikan bahawa medan intValue tidak terdapat 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. Kesimpulannya

Artikel tersebut menggambarkan cara mengabaikan bidang pada siriisasi - pertama dengan nama, kemudian secara langsung, dan akhirnya - kami mengabaikan keseluruhan jenis java dengan MixIns dan kami menggunakan penapis untuk lebih banyak kawalan output.

Pelaksanaan semua contoh dan coretan kod ini terdapat di projek GitHub saya.