Memetakan Objek JSON Dinamis dengan Jackson

1. Perkenalan

Bekerja dengan struktur data JSON yang telah ditentukan dengan Jackson sangatlah mudah. Namun, terkadang kita perlu menangani objek JSON dinamis , yang memiliki properti tidak diketahui .

Dalam tutorial singkat ini, kita akan melihat beberapa cara memetakan objek JSON dinamis ke dalam kelas Java.

Perhatikan bahwa dalam semua pengujian, kami menganggap kami memiliki field objectMapper jenis com.fasterxml.jackson.databind.ObjectMapper .

2. Menggunakan JsonNode

Misalkan kita ingin memproses spesifikasi produk di webshop. Semua produk memiliki beberapa sifat yang sama, tetapi ada yang lain, yang bergantung pada jenis produk.

Misalnya, kami ingin mengetahui rasio aspek tampilan ponsel, tetapi properti ini tidak masuk akal untuk sepatu.

Struktur datanya terlihat seperti ini:

{ "name": "Pear yPhone 72", "category": "cellphone", "details": { "displayAspectRatio": "97:3", "audioConnector": "none" } }

Kami menyimpan properti dinamis di objek detail .

Kita dapat memetakan properti umum dengan kelas Java berikut:

class Product { String name; String category; // standard getters and setters }

Selain itu, kita membutuhkan representasi yang tepat untuk objek details . Misalnya, com.fasterxml.jackson.databind.JsonNode dapat menangani kunci dinamis .

Untuk menggunakannya, kita harus menambahkannya sebagai field ke kelas Produk kita :

class Product { // common fields JsonNode details; // standard getters and setters }

Akhirnya, kami memverifikasi bahwa itu berfungsi:

String json = ""; Product product = objectMapper.readValue(json, Product.class); assertThat(product.getName()).isEqualTo("Pear yPhone 72"); assertThat(product.getDetails().get("audioConnector").asText()).isEqualTo("none");

Namun, kami memiliki masalah dengan solusi ini. Kelas kita bergantung pada perpustakaan Jackson karena kita memiliki bidang JsonNode .

3. Menggunakan Peta

Kami dapat mengatasi masalah ini dengan menggunakan java.util.Map untuk bidang detail . Lebih tepatnya, kita harus menggunakan Map .

Yang lainnya bisa tetap sama:

class Product { // common fields Map details; // standard getters and setters }

Dan kemudian kami dapat memverifikasinya dengan tes:

String json = ""; Product product = objectMapper.readValue(json, Product.class); assertThat(product.getName()).isEqualTo("Pear yPhone 72"); assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");

4. Menggunakan @JsonAnySetter

Solusi sebelumnya bagus ketika sebuah objek hanya berisi properti dinamis. Namun, terkadang kami memiliki properti tetap dan dinamis yang dicampur dalam satu objek JSON .

Misalnya, kita mungkin perlu meratakan representasi produk kita:

{ "name": "Pear yPhone 72", "category": "cellphone", "displayAspectRatio": "97:3", "audioConnector": "none" }

Kita dapat memperlakukan struktur seperti ini sebagai objek dinamis. Sayangnya, itu berarti kita tidak dapat mendefinisikan properti umum - kita juga harus memperlakukannya secara dinamis.

Alternatifnya, kita bisa menggunakan @JsonAnySetter untuk menandai metode untuk menangani properti tambahan yang tidak diketahui . Metode seperti itu harus menerima dua argumen: nama dan nilai properti:

class Product { // common fields Map details = new LinkedHashMap(); @JsonAnySetter void setDetail(String key, Object value) { details.put(key, value); } // standard getters and setters }

Catatan, kita harus membuat instance objek details untuk menghindari NullPointerExceptions .

Karena kita menyimpan properti dinamis dalam Peta , kita dapat menggunakannya dengan cara yang sama seperti sebelumnya:

String json = ""; Product product = objectMapper.readValue(json, Product.class); assertThat(product.getName()).isEqualTo("Pear yPhone 72"); assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");

5. Membuat Deserializer Kustom

Untuk kebanyakan kasus, solusi ini berfungsi dengan baik. Namun, terkadang kita membutuhkan lebih banyak kendali. Misalnya, kita bisa menyimpan informasi deserialization tentang objek JSON kita dalam database.

Kami dapat menargetkan situasi tersebut dengan deserializer khusus. Karena ini adalah topik yang kompleks, kami membahasnya di artikel yang berbeda, Memulai Deserialisasi Kustom di Jackson.

6. Kesimpulan

Dalam artikel ini, kami melihat beberapa cara menangani objek JSON dinamis dengan Jackson.

Seperti biasa, contoh tersedia di GitHub.