डीसीरियलाइजेशन के दौरान, Gson एक JSON ऑब्जेक्ट एक्सपेक्ट कर सकता है लेकिन JSON ऐरे पा सकता है। चूंकि यह एक को दूसरे में कन्वर्ट नहीं कर सकता, यह रनटाइम पर एरर थ्रो करता है: "JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY"।
एरर का उदाहरण
import com.google.gson.Gson;
public class GsonErrorTest {
public static void main(String args[]) throws Exception {
String json = "{\"employee\":[{\"name\":\"Raja Ramesh\", \"technology\":\"java\"}]}";
Gson gson = new Gson();
Software software = gson.fromJson(json, Software.class);
System.out.println(software);
}
}
class Software {
Employee employee; // सिंगल ऑब्जेक्ट - लेकिन JSON में ऐरे है!
}
class Employee {
String name;
String technology;
}
आउटपुट (एरर)
Exception in thread "main"
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 14
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(...)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
at com.google.gson.stream.JsonReader.expect(JsonReader.java:339)
समाधान: POJO टाइप को Collection या Array में बदलें
import java.util.List;
import com.google.gson.Gson;
public class GsonListTest {
public static void main(String args[]) throws Exception {
String jsonString = "{\"employees\":[{\"name\":\"Raja Ramesh\", \"technology\":\"Java\"}]}";
Gson gson = new Gson();
Software software = gson.fromJson(jsonString, Software.class);
System.out.println(software);
}
}
class Software {
List<Employee> employees; // List<Employee> के बजाय Employee
@Override
public String toString() {
return "Software [employees=" + employees + "]";
}
}
class Employee {
String name;
String technology;
@Override
public String toString() {
return "Employee [name=" + name + ", technology=" + technology + "]";
}
}
आउटपुट (सफल)
Software [employees=[Employee [name=Raja Ramesh, technology=Java]]]
एरर के सामान्य कारण
| JSON स्ट्रक्चर | POJO फील्ड | समस्या |
|---|---|---|
| {"items": [...]} | Item items; | ऑब्जेक्ट vs ऐरे |
| [...] | MyClass obj; | रूट ऐरे vs ऑब्जेक्ट |
| {"data": {...}} | List<Data> data; | ऑब्जेक्ट vs लिस्ट |
समाधान के विकल्प
- List<T>: सबसे आम, फ्लेक्सिबल
- T[]: फिक्स्ड-साइज ऐरे
Collection<T>: इंटरफेस-आधारितTypeToken: जेनेरिक टाइप के लिए (List<MyClass>)
TypeToken का उपयोग
Type listType = new TypeToken<List<Employee>>(){}.getType();
List<Employee> employees = gson.fromJson(jsonArrayString, listType);
रूट लेवल ऐरे के लिए
// JSON: [{"name":"A"}, {"name":"B"}]
Employee[] employees = gson.fromJson(jsonString, Employee[].class);
// या
List<Employee> list = gson.fromJson(jsonString, new TypeToken<List<Employee>>(){}.getType());
बेस्ट प्रैक्टिस
- JSON स्ट्रक्चर को POJO से मैच करें पहले कोड लिखने से
- ऑनलाइन JSON व्यूअर का उपयोग करके स्ट्रक्चर विज़ुअलाइज़ करें
- कॉम्प्लेक्स स्ट्रक्चर्स के लिए @SerializedName का उपयोग करें
- एरर मैसेज में कॉलम नंबर समस्या का स्थान इंगित करता है