Bermula dengan Deserialization Custom di Jackson

1. Gambaran keseluruhan

Tutorial ringkas ini akan menggambarkan cara menggunakan Jackson 2 untuk mendeserisasi JSON menggunakan Deserializer tersuai .

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

2. Deserialisasi Piawai

Mari mulakan dengan mendefinisikan 2 entiti dan lihat bagaimana Jackson akan mendeserialisasikan representasi JSON kepada entiti ini tanpa penyesuaian:

public class User { public int id; public String name; } public class Item { public int id; public String itemName; public User owner; }

Sekarang, mari kita tentukan representasi JSON yang ingin kita deserialisasi:

{ "id": 1, "itemName": "theItem", "owner": { "id": 2, "name": "theUser" } }

Dan akhirnya, mari kita hapus JSON ini ke Entiti Java:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

3. Custom Deserializer pada ObjectMapper

Dalam contoh sebelumnya, representasi JSON sepadan dengan entiti java dengan sempurna - seterusnya, kami akan mempermudah JSON:

{ "id": 1, "itemName": "theItem", "createdBy": 2 }

Apabila membatalkan pemasangan ke entiti yang sama - secara lalai, ini tentu akan gagal:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item), not marked as ignorable (3 known properties: "id", "owner", "itemName"]) at [Source: [email protected]; line: 1, column: 43] (through reference chain: org.baeldung.jackson.dtos.Item["createdBy"])

Kami akan menyelesaikannya dengan melakukan deserialization kita sendiri dengan Deserializer tersuai :

public class ItemDeserializer extends StdDeserializer { public ItemDeserializer() { this(null); } public ItemDeserializer(Class vc) { super(vc); } @Override public Item deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); int id = (Integer) ((IntNode) node.get("id")).numberValue(); String itemName = node.get("itemName").asText(); int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue(); return new Item(id, itemName, new User(userId, null)); } }

Seperti yang anda lihat, deserializer berfungsi dengan representasi Jackson standard dari JSON - the JsonNode . Setelah input JSON ditunjukkan sebagai JsonNode , kita sekarang dapat mengekstrak maklumat yang relevan darinya dan membina entiti Item kita sendiri .

Ringkasnya, kita perlu mendaftarkan deserializer khusus ini dan hanya mendeserialisasikan JSON seperti biasa:

ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Item.class, new ItemDeserializer()); mapper.registerModule(module); Item readValue = mapper.readValue(json, Item.class);

4. Deserializer Tersuai di Kelas

Sebagai alternatif, kita juga boleh mendaftarkan deserializer secara langsung di kelas :

@JsonDeserialize(using = ItemDeserializer.class) public class Item { ... }

Dengan deserializer yang ditentukan di peringkat kelas, tidak perlu mendaftarkannya di ObjectMapper - mapper lalai akan berfungsi dengan baik:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

Jenis konfigurasi per kelas ini sangat berguna dalam situasi di mana kita mungkin tidak mempunyai akses langsung ke ObjectMapper mentah untuk dikonfigurasi.

5. Kesimpulan

Artikel ini menunjukkan cara memanfaatkan Jackson 2 untuk membaca input JSON bukan standard - dan cara memetakan input tersebut ke mana-mana graf entiti java dengan kawalan penuh terhadap pemetaan.

Pelaksanaan semua contoh dan coretan kod ini dapat dilihat di GitHub - ini adalah projek berasaskan Maven, jadi mudah untuk diimport dan dijalankan sebagaimana adanya.