"Hai kawan!"

"Hei, Diego."

"Saya lihat di sini anda telah mempelajari asas penyiaran JSON?"

"Apa maksud awak 'asas'? Saya tahu banyak!"

"Begitu naif. Anda tidak tahu separuh daripadanya. Sepuluh peratus paling baik."

"Kau gurau je. Ada apa lagi?"

"Penyahserialisasian hierarki objek (penyahserialisasian polimorfik), penyahserialisasian koleksi, dan banyak lagi! Rangka kerja Jackson adalah besar dan berkuasa. Sejujurnya, anda baru sahaja mula menconteng permukaan."

"Baiklah, kemudian beritahu saya mengenainya - saya semua telinga."

"Saya sangat seronok menjadi lebih bijak dengan setiap pelajaran!"

"Baiklah, saya berbesar hati untuk membantu, kawan robot saya!"

"Awak dah bersedia? Lepas tu dengar."

"Seperti yang telah anda pelajari, anotasi digunakan untuk kedua-dua penyirian dan penyahserikatan. Dalam amalan, penyiaran memerlukan maklumat yang jauh lebih sedikit daripada penyahserikatan. Contohnya:"

kelas Java JSON
class Cat
{
 public String name = "missy";
 public Cat[] cats = new Cat[0];
}
{
 "name": "missy",
 "cats": []
}
class Cat
{
 public String name = "missy";
 public List cats = new ArrayList<Cat>();
}
{
 "name": "missy",
 "cats": []
}
class Cat
{
 public String name = "missy";
 public List cats = new LinkedList<Cat>();
}
{
 "name": "missy",
 "cats": []
}

"Instance Array, ArrayList, LinkedList dan kelas lain ditukar menjadi tatasusunan JSON."

"Tetapi apabila anda menyahsiri tatasusunan JSON, objek apakah yang perlu anda buat: ArrayList atau LinkedList?"

"Betul. Jika ahli kelas ialah antara muka (cth Public List<Cat> cats ), apakah objek yang harus dikaitkan dengannya?"

"Kami boleh menambah anotasi tambahan pada medan atau secara eksplisit menunjukkan kelas sasaran semasa penyahserikatan. Lihat contoh ini:"

Tukar objek daripada JSON
public static void main(String[] args) throws IOException
{
 String jsonString = ""{\"name\":\"Missy\",\"cats\":[{\"name\":\"Timmy\"},{\"name\":\"Killer\"}]}"";
 StringReader reader = new StringReader(jsonString);
 ObjectMapper mapper = new ObjectMapper();
 Cat cat = mapper.readValue(reader, TypeFactory.collectionType(ArrayList.class, Cat.class));
}
Kelas yang objeknya dinyahsiri daripada JSON
@JsonAutoDetect
class Cat {
 public String name;
 public List&ltCat> cats = new ArrayList<>();
 Cat() {
 }
}

" Dalam erti kata lain, kita boleh menggunakan parameter kedua kaedah readValue pemeta untuk lulus senarai kelas untuk digunakan semasa penyahserikatan."

"Saya suka. Itu mudah. ​​Jadi anda boleh menyahsiri tatasusunan JSON kepada apa sahaja yang anda perlukan, ArrayList atau LinkedList.

"Anda juga menyebut menggunakan anotasi. Bagaimana anda melakukannya?"

"Mudah sahaja. Contohnya:"

Tukar objek daripada JSON
public static void main(String[] args) throws IOException
{
 String jsonString = ""{\"name\":\"Missy\",\"cats\":[{\"name\":\"Timmy\"},{\"name\":\"Killer\"}]}"";
 StringReader reader = new StringReader(jsonString);

 ObjectMapper mapper = new ObjectMapper();

 Cat cat = mapper.readValue(reader, Cat.class);
}
Kelas yang objeknya dinyahsiri daripada JSON
@JsonAutoDetect
class Cat
{
 public String name;
 @JsonDeserialize(as = ArrayList.class, contentAs = Cat.class)
 public List&ltCat> cats = new ArrayList<>();
 Cat() {
 }
}

"Kami hanya menambah anotasi @JsonDeserialize(as = ArrayList.class, contentAs = Cat.class) pada baris 5 untuk menunjukkan pelaksanaan antara muka Senarai yang hendak digunakan."

"Ah. Saya faham. Itu sebenarnya agak mudah."

"Tetapi ada lagi. Katakan jenis data dalam Senarai juga merupakan antara muka! Apa yang akan anda lakukan?"

"Adakah kita menggunakan anotasi di sini juga?"

"Ya, yang sama. Anda juga boleh menggunakannya untuk menunjukkan jenis parameter. Seperti ini:"

Jenis koleksi Bagaimana untuk menetapkan jenis data
Senaraikan @JsonDeserialize(contentAs = ValueTypeImpl.class)
Peta @JsonDeserialize(keyAs = KeyTypeImpl.class)

"Cool! Terdapat banyak anotasi yang diperlukan untuk pelbagai situasi yang tidak dapat kita jangkakan."

"Bukan itu sahaja. Dan itu membawa kita ke kursus utama: dalam projek sebenar, kelas sering kali mewarisi kelas asas atau antara muka yang sama, yang digunakan hampir di mana-mana. Dan sekarang bayangkan bahawa anda perlu menyahsiri struktur data yang mengandungi kelas sedemikian. Sebagai contoh:"

Tukar objek kepada JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;

 Dog dog = new Dog();
 dog.name = "Killer";
 dog.age = 8;
 dog.owner = "Bill Jefferson";

 ArrayList<Pet> pets = new ArrayList<Pet>();
 pets.add(cat);
 pets.add(dog);

 StringWriter writer = new StringWriter();
 ObjectMapper mapper = new ObjectMapper();
 mapper.writeValue(writer, pets);
 System.out.println(writer.toString());
}
Kelas yang objeknya ditukar kepada JSON
@JsonAutoDetect
class Pet
{
 public String name;
}

@JsonAutoDetect
class Cat extends Pet
{
 public int age;
}

@JsonAutoDetect
class Dog extends Pet
{
 public int age;
 public String owner;
}
Hasil siri dan output skrin:
[
 { "name" : "Missy", "age" : 5},
 { "name" : "Killer", "age" : 8 , "owner" : "Bill Jeferson"}
]

"Beri perhatian kepada hasil bersiri."

"Kami tidak boleh menyahsiri data ini menjadi objek Java, kerana ia pada asasnya tidak dapat dibezakan daripada data untuk kelas lain."

"Terdapat beberapa ciri yang membezakan: Anjing mempunyai medan pemilik."

"Ya, tetapi medan ini mungkin batal atau ia boleh dilangkau sepenuhnya semasa penyirian."

"Nah, tidakkah kita boleh menentukan jenis data menggunakan anotasi yang kita tahu?"

"Tidak. Selepas penyahserikatan, satu koleksi harus mempunyai pelbagai objek Kucing dan Anjing, serta sedozen kelas lain yang boleh diwarisi daripada Binatang."

"Apa yang boleh anda lakukan di sini?"

"Dua perkara digunakan di sini."

"Pertama, medan tertentu dipilih untuk membezakan satu jenis daripada yang lain. Jika tidak ada, maka ia dicipta."

"Kedua, terdapat anotasi khas yang membolehkan anda mengawal proses «deserialisasi polimorfik». Berikut ialah perkara yang boleh anda lakukan:"

Tukar objek kepada JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;

 Dog dog = new Dog();
 dog.name = "Killer";
 dog.age = 8;
 dog.owner = "Bill Jeferson";

 House house = new House();
 house.pets.add(dog);
 house.pets.add(cat);

 StringWriter writer = new StringWriter();
 ObjectMapper mapper = new ObjectMapper();
 mapper.writeValue(writer, house);
 System.out.println(writer.toString());
}
Kelas yang objeknya ditukar kepada JSON
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")
})
class Pet
{
 public String name;
}

class Cat extends Pet
{
 public int age;
}

class Dog extends Pet
{
 public int age;
 public String owner;
}

class House
{
 public List&ltPet> pets = new ArrayList<>();
}
Hasil siri dan output skrin:
{
 "pets" : [
 {"type" : "dog", "name" : "Killer", "age" : 8, "owner" : "Bill Jeferson"},
 {"type" : "cat", "name" : "Missy", "age" : 5}
]
}

Menggunakan anotasi, kami menunjukkan bahawa perwakilan JSON akan mengandungi medan khas yang dipanggil jenis yang akan menyimpan kucing nilai untuk kelas Kucing dan anjing nilai untuk kelas Anjing . Maklumat ini cukup untuk menyahsiri objek dengan betul: semasa penyahserikatan, jenis objek yang akan dibuat akan ditentukan oleh nilai medan jenis.

"Kadangkala nama kelas digunakan sebagai nilai medan jenis (cth «com.example.entity.Cat.class»), tetapi ini bukan amalan yang baik. Bagaimanakah aplikasi luaran yang menerima JSON kami mengetahui nama kelas kita? Lebih teruk, kelas kadangkala dinamakan semula. Adalah lebih baik untuk menggunakan beberapa nama unik untuk mengenal pasti kelas tertentu."

"Cool! Sigh. Saya tidak sedar penyahserialisasian adalah begitu rumit. Dan banyak lagi yang boleh anda sesuaikan."

"Ya. Ini adalah konsep baru untuk anda, tetapi ini adalah jenis pengetahuan praktikal yang akan menjadikan anda seorang pengaturcara yang genius."

"Amigo ialah seorang pengaturcara yang hebat. Sejuk!"

"OK. Pergi dan berehat."