Jackson Unmarshalling JSON dengan Harta Tidak Diketahui

1. Gambaran keseluruhan

Dalam artikel ini, kita akan melihat proses unmarshalling dengan Jackson 2.x - khususnya bagaimana menangani kandungan JSON dengan sifat yang tidak diketahui .

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

2. Nyahpasang JSON Dengan Medan Tambahan / Tidak Diketahui

Input JSON terdapat dalam semua bentuk dan ukuran - dan selalunya, kita perlu memetakannya ke objek Java yang telah ditentukan dengan sejumlah bidang. Tujuannya adalah untuk mengabaikan sifat JSON yang tidak dapat dipetakan ke medan Java yang ada .

Sebagai contoh, katakan kita perlu melepaskan JSON ke entiti Java berikut:

public class MyDto { private String stringValue; private int intValue; private boolean booleanValue; // standard constructor, getters and setters }

2.1. UnrecognizedPropertyException pada Medan Tidak Diketahui

Cuba melepaskan JSON dengan sifat yang tidak diketahui pada Java Entity yang sederhana ini akan membawa kepada com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException :

@Test(expected = UnrecognizedPropertyException.class) public void givenJsonHasUnknownValues_whenDeserializing_thenException() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); }

Ini akan gagal dengan pengecualian berikut:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stringValue2" (class org.baeldung.jackson.ignore.MyDto), not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])

2.2. Berurusan dengan Medan Tidak Diketahui Menggunakan ObjectMapper

Kita sekarang boleh mengkonfigurasi ObjectMapper penuh untuk mengabaikan sifat yang tidak diketahui di JSON:

new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Kita seharusnya dapat membaca JSON semacam ini menjadi entiti Java yang telah ditentukan:

@Test public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknowns_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }

2.3. Berurusan dengan Medan Tidak Diketahui di Peringkat Kelas

Kami juga dapat menandakan satu kelas sebagai menerima medan yang tidak diketahui , dan bukannya keseluruhan Jackson ObjectMapper :

@JsonIgnoreProperties(ignoreUnknown = true) public class MyDtoIgnoreUnknown { ... }

Sekarang, kita seharusnya dapat menguji tingkah laku yang sama seperti sebelumnya - medan yang tidak diketahui hanya diabaikan dan hanya bidang yang diketahui dipetakan

@Test public void givenJsonHasUnknownValuesButIgnoredOnClass_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDtoIgnoreUnknown readValue = mapper .readValue(jsonAsString, MyDtoIgnoreUnknown.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }

3. Cabut JSON yang Tidak Lengkap

Begitu juga dengan medan tambahan yang tidak diketahui, membuang JSON yang tidak lengkap - JSON yang tidak mengandungi semua medan dalam kelas Java - tidak menjadi masalah dengan Jackson:

@Test public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a","booleanValue":true}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); }

4. Kesimpulan

Artikel ini membahas deserialisasi JSON dengan tambahan, sifat yang tidak diketahui, menggunakan Jackson.

Ini adalah salah satu perkara yang paling umum untuk dikonfigurasi ketika bekerja dengan Jackson kerana sering kali kita perlu memetakan hasil JSON dari API REST luaran ke perwakilan Java dalaman entiti API.

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