"हाय दोस्त!"

"अरे, डिएगो।"

"मैं यहाँ देख रहा हूँ कि आपने JSON क्रमांकन की मूल बातें सीख ली हैं?"

"बुनियादी बातों से आपका क्या मतलब है? मैं बहुत कुछ जानता हूँ!"

"इतना भोला। आप इसका आधा नहीं जानते। दस प्रतिशत सबसे अच्छा।"

"तुम मजाक कर रहे हो। और क्या है?"

"एक वस्तु पदानुक्रम का अक्रमांकन (बहुरूपी अक्रमांकन), संग्रहों का अक्रमांकन, और बहुत कुछ! जैक्सन ढांचा बड़ा और शक्तिशाली है। ईमानदारी से, आपने केवल सतह को खरोंचना शुरू किया है।"

"ठीक है, फिर मुझे इसके बारे में बताओ - मैं सब कान हूँ।"

"मैं वास्तव में प्रत्येक पाठ के साथ होशियार होने का आनंद ले रहा हूँ!"

"ठीक है, यह मेरी मदद करने में खुशी है, मेरे रोबोट मित्र!"

"क्या आप तैयार हैं? तो सुनो।"

"जैसा कि आप पहले ही सीख चुके हैं, एनोटेशन का उपयोग क्रमांकन और अक्रमांकन दोनों के लिए किया जाता है। व्यवहार में, क्रमांकन के लिए अक्रमांकन की तुलना में बहुत कम जानकारी की आवश्यकता होती है। उदाहरण के लिए:"

जावा वर्ग 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": []
}

"ऐरे, ऐरेलिस्ट, लिंक्डलिस्ट और अन्य वर्गों के उदाहरण JSON सरणी में बदल दिए गए हैं।"

"लेकिन जब आप एक JSON सरणी को डिसेर्बलाइज़ करते हैं, तो आपको कौन सी वस्तु बनानी चाहिए: एक ArrayList या एक LinkedList?"

"ठीक है। यदि एक वर्ग सदस्य एक इंटरफ़ेस है (उदाहरण के लिए public List<Cat>cats ), तो किस वस्तु को इसके लिए जिम्मेदार ठहराया जाना चाहिए?"

"हम क्षेत्र में अतिरिक्त एनोटेशन जोड़ सकते हैं या अक्रमांकन के दौरान लक्ष्य वर्गों को स्पष्ट रूप से इंगित कर सकते हैं। इस उदाहरण को देखें:"

किसी ऑब्जेक्ट को 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));
}
एक वर्ग जिसका ऑब्जेक्ट JSON से deserialized है
@JsonAutoDetect
class Cat {
 public String name;
 public List&ltCat> cats = new ArrayList<>();
 Cat() {
 }
}

"दूसरे शब्दों में, हम deserialization के दौरान उपयोग करने के लिए कक्षाओं की सूची पास करने के लिए मैपर . readValue विधि के दूसरे पैरामीटर का उपयोग कर सकते हैं ।"

"मुझे यह पसंद है। यह सुविधाजनक है। इसलिए आप जो कुछ भी चाहते हैं, एक ArrayList या एक LinkedList में एक JSON सरणी को deserialize कर सकते हैं।

"आपने एनोटेशन का उपयोग करने का भी उल्लेख किया है। आप यह कैसे करते हैं?"

"यह आसान है। उदाहरण के लिए:"

किसी ऑब्जेक्ट को 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);
}
एक वर्ग जिसका ऑब्जेक्ट JSON से deserialized है
@JsonAutoDetect
class Cat
{
 public String name;
 @JsonDeserialize(as = ArrayList.class, contentAs = Cat.class)
 public List&ltCat> cats = new ArrayList<>();
 Cat() {
 }
}

"हम बस एनोटेशन @JsonDeserialize(as = ArrayList.class, contentAs = Cat.class) को पंक्ति 5 में जोड़ते हैं ताकि यह इंगित किया जा सके कि सूची इंटरफ़ेस का कौन सा कार्यान्वयन उपयोग करना है।"

"आह। मैं समझ गया। यह वास्तव में काफी सरल है।"

"लेकिन वहाँ अधिक है। मान लीजिए कि सूची में डेटा प्रकार भी एक इंटरफ़ेस है! आप क्या करेंगे?"

"क्या हम यहाँ भी एनोटेशन का उपयोग करते हैं?"

"हाँ, वही। आप इसका उपयोग पैरामीटर प्रकार को इंगित करने के लिए भी कर सकते हैं। इस तरह:"

संग्रह प्रकार डेटा प्रकार कैसे सेट करें
सूची @JsonDeserialize(contentAs = ValueTypeImpl.class)
नक्शा @JsonDeserialize(keyAs = KeyTypeImpl.class)

"कूल! ऐसी विभिन्न स्थितियों के लिए वास्तव में बहुत सारे एनोटेशन की आवश्यकता होती है जिनकी हम आशा नहीं कर सकते।"

"यह सब नहीं है। और यह हमें मुख्य पाठ्यक्रम में लाता है: वास्तविक परियोजनाओं में, कक्षाएं अक्सर समान आधार वर्ग या इंटरफ़ेस को विरासत में लेती हैं, जो वस्तुतः हर जगह उपयोग किया जाता है। और अब कल्पना करें कि आपको ऐसी कक्षाओं वाली डेटा संरचना को डीसेरलाइज़ करने की आवश्यकता है। उदाहरण के लिए:"

किसी वस्तु को 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());
}
एक वर्ग जिसका ऑब्जेक्ट 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;
}
क्रमांकन परिणाम और स्क्रीन आउटपुट:
[
 { "name" : "Missy", "age" : 5},
 { "name" : "Killer", "age" : 8 , "owner" : "Bill Jeferson"}
]

"क्रमांकन के परिणाम पर ध्यान दें।"

"हम इस डेटा को जावा ऑब्जेक्ट में डिसेर्बलाइज़ नहीं कर सकते, क्योंकि यह अन्य वर्गों के डेटा से अनिवार्य रूप से अप्रभेद्य है।"

"कुछ विशिष्ट विशेषताएं हैं: कुत्ते का मालिक क्षेत्र है।"

"हाँ, लेकिन यह क्षेत्र अशक्त हो सकता है या इसे क्रमांकन के दौरान पूरी तरह से छोड़ दिया जा सकता है।"

"ठीक है, क्या हम उन एनोटेशन का उपयोग करके डेटा प्रकार निर्दिष्ट नहीं कर सकते जिन्हें हम जानते हैं?"

"नहीं। डिसेरिएलाइज़ेशन के बाद, एक संग्रह में विभिन्न कैट और डॉग ऑब्जेक्ट होने चाहिए, साथ ही एक दर्जन अन्य वर्ग जो पेट से इनहेरिट कर सकते हैं।"

"आप यहां दुनिया में क्या कर सकते हैं?"

"यहाँ दो चीजों का उपयोग किया जाता है।"

"सबसे पहले, एक प्रकार को दूसरे से अलग करने के लिए एक निश्चित क्षेत्र चुना जाता है। यदि कोई नहीं है, तो इसे बनाया जाता है।"

"दूसरा, विशेष एनोटेशन हैं जो आपको «बहुरूपी अक्रमांकन» की प्रक्रिया को नियंत्रित करने देते हैं। यहां बताया गया है कि आप क्या कर सकते हैं:"

किसी वस्तु को 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());
}
एक वर्ग जिसका ऑब्जेक्ट 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<>();
}
क्रमांकन परिणाम और स्क्रीन आउटपुट:
{
 "pets" : [
 {"type" : "dog", "name" : "Killer", "age" : 8, "owner" : "Bill Jeferson"},
 {"type" : "cat", "name" : "Missy", "age" : 5}
]
}

एनोटेशन का उपयोग करते हुए, हम इंगित करते हैं कि JSON प्रतिनिधित्व में एक विशेष फ़ील्ड होगा जिसे टाइप कहा जाता है जो कैट क्लास के लिए वैल्यू कैट और डॉग क्लास के लिए वैल्यू डॉग को होल्ड करेगा। यह जानकारी किसी वस्तु को ठीक से डिसेरिएलाइज़ करने के लिए पर्याप्त है: डिसेरिएलाइज़ेशन के दौरान, बनाई जाने वाली वस्तु का प्रकार प्रकार फ़ील्ड के मान द्वारा निर्धारित किया जाएगा।

"कभी-कभी वर्ग नाम का उपयोग प्रकार फ़ील्ड के मान के रूप में किया जाता है (उदाहरण के लिए «com.example.entity.Cat.class»), लेकिन यह एक अच्छा अभ्यास नहीं है। हमारे JSON प्राप्त करने वाले बाहरी एप्लिकेशन को नामों का पता कैसे चलेगा हमारी कक्षाएं? इससे भी बदतर, कक्षाओं का कभी-कभी नाम बदल दिया जाता है। किसी विशिष्ट वर्ग की पहचान करने के लिए कुछ अद्वितीय नाम का उपयोग करना बेहतर होता है।"

"कूल! आह। मुझे नहीं पता था कि डिसेरिएलाइज़ेशन इतना जटिल था। और इतना कुछ है कि आप फ़ाइन-ट्यून कर सकते हैं।"

"हाँ। ये आपके लिए नई अवधारणाएँ हैं, लेकिन यह एक तरह का व्यावहारिक ज्ञान है जो आपको एक जीनियस प्रोग्रामर बना देगा।"

"एमिगो एक अच्छा प्रोग्रामर है। अच्छा!"

"ठीक है। जाओ और आराम करो।"