2015-11-10 13 views
5

(इस पोस्ट के नीचे प्रदान की एक नमूना जवाब के साथ एक canonical question करने के लिए है।)जीसन से जेसन ने जेसन सिंटैक्स अपवाद क्यों फेंक दिया: कुछ प्रकार की उम्मीद है लेकिन कुछ अन्य प्रकार था?


मैं Gson#fromJson(String, Class) के साथ एक कस्टम POJO प्रकार में कुछ JSON सामग्री deserialize करने के लिए कोशिश कर रहा हूँ।

कोड

import com.google.gson.Gson; 

public class Sample { 
    public static void main(String[] args) { 
     String json = "{\"nestedPojo\":[{\"name\":null, \"value\":42}]}"; 
     Gson gson = new Gson(); 
     gson.fromJson(json, Pojo.class); 
    } 
} 

class Pojo { 
    NestedPojo nestedPojo; 
} 

class NestedPojo { 
    String name; 
    int value; 
} 

का यह टुकड़ा पालन अपवाद

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196) 
    at com.google.gson.Gson.fromJson(Gson.java:810) 
    at com.google.gson.Gson.fromJson(Gson.java:775) 
    at com.google.gson.Gson.fromJson(Gson.java:724) 
    at com.google.gson.Gson.fromJson(Gson.java:696) 
    at com.example.Sample.main(Sample.java:23) 
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo 
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189) 
    ... 7 more 

क्यों नहीं Gson ठीक से मेरी JSON टेक्स्ट मेरे POJO प्रकार में बदल सकते हैं फेंकता है?

उत्तर

22

अपवाद संदेश के रूप में कहा गया है

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo 

जबकि deserializing, Gson एक JSON ऑब्जेक्ट उम्मीद कर रहा था, लेकिन एक JSON सारणी पाया। चूंकि यह एक से दूसरे में परिवर्तित नहीं हो सका, इसने अपवाद को फेंक दिया।

JSON प्रारूप का वर्णन here है। संक्षेप में, यह निम्न प्रकारों को परिभाषित करता है: ऑब्जेक्ट्स, सरणी, स्ट्रिंग्स, संख्याएं, null, और बूलियन मान true और false

Gson (और सबसे JSON पारसर्स) में, निम्न मैपिंग मौजूद हैं: एक जावा String को JSON स्ट्रिंग के नक्शे; जावा पर एक JSON संख्या मानचित्र Number प्रकार; एक JSON सरणी मानचित्र Collection प्रकार या सरणी प्रकार के लिए; जावा पर एक JSON ऑब्जेक्ट मैप्स Map टाइप या, आमतौर पर, एक कस्टम POJO प्रकार (पहले उल्लेख नहीं किया गया); null जावा के null पर मानचित्र, और बूलियन मान जावा के true और false पर मानचित्र मानते हैं।

JSON सामग्री है कि आप प्रदान करते हैं और इसी प्रकार आप का अनुरोध किया है करने के लिए यह deserialize की कोशिश करता है के माध्यम से Gson दोहराता। यदि सामग्री मेल नहीं खाती है या अपेक्षित प्रकार में परिवर्तित नहीं की जा सकती है, तो यह एक प्रासंगिक अपवाद फेंक देगा।

आपके मामले में, आप जड़ में निम्नलिखित JSON

{ 
    "nestedPojo": [ 
     { 
      "name": null, 
      "value": 42 
     } 
    ] 
} 

प्रदान की, इस एक JSON ऑब्जेक्ट जो एक सदस्य nestedPojo नामित जो एक JSON सारणी होता है। उस JSON सरणी में एक एकल तत्व, दो सदस्य के साथ एक और JSON ऑब्जेक्ट होता है। मैपिंग पहले परिभाषित ध्यान में रखते हुए, तो आप इस JSON एक जावा वस्तु है जो एक क्षेत्र कुछ Collection या सरणी प्रकार, जहां कि प्रकार क्रमश: name और value, नामित दो क्षेत्रों को परिभाषित करता है की nestedPojo नामक को मैप करने के उम्मीद थी।

हालांकि, अगर आप एक क्षेत्र

NestedPojo nestedPojo; 

वह यह है कि न तो एक सरणी प्रकार, और न ही एक Collection प्रकार होने के रूप में अपने Pojo प्रकार परिभाषित किया है। जीसन इस क्षेत्र के लिए संबंधित JSON deserialize नहीं कर सकते हैं।

  • अपेक्षित प्रकार

    { 
        "nestedPojo": { 
         "name": null, 
         "value": 42 
        } 
    } 
    
  • मैच के लिए एक Collection या सरणी प्रकार

    List<NestedPojo> nestedPojo; // consider changing the name and using @SerializedName 
    NestedPojo[] nestedPojo; 
    
  • उम्मीद करने के लिए अपने Pojo प्रकार बदलें आपके JSON बदलें:

    इसके बजाय, आप 3 विकल्प हैं

  • लिखें और reg NestedPojo के लिए अपने स्वयं के पार्सिंग नियमों के साथ एक कस्टम deserializer ister। अपने json में उदाहरण

    class Custom implements JsonDeserializer<NestedPojo> { 
        @Override 
        public NestedPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
         NestedPojo nestedPojo = new NestedPojo(); 
         JsonArray jsonArray = json.getAsJsonArray(); 
         if (jsonArray.size() != 1) { 
          throw new IllegalStateException("unexpected json"); 
         } 
         JsonObject jsonObject = jsonArray.get(0).getAsJsonObject(); // get only element 
         JsonElement jsonElement = jsonObject.get("name"); 
         if (!jsonElement.isJsonNull()) { 
          nestedPojo.name = jsonElement.getAsString(); 
         } 
         nestedPojo.value = jsonObject.get("value").getAsInt(); 
         return nestedPojo; 
        } 
    } 
    
    Gson gson = new GsonBuilder().registerTypeAdapter(NestedPojo.class, new Custom()).create(); 
    
7
class Pojo { 
    NestedPojo nestedPojo; 
} 

के लिए आप तो या तो nestedPojo की एक सरणी है आप कोड

NestedPojo[] nestedPojo; 

बदल सकते हैं या आप json स्ट्रिंग को बदलने

String json = "{\"nestedPojo\":{\"name\":null, \"value\":42}}"; 
संबंधित मुद्दे

 संबंधित मुद्दे