मुझे पता है कि यह एक काफी पुराना सवाल है, लेकिन मैं जेन्सन को नेस्टेड जेनेरिक डीसिएरलाइज़ करने के लिए एक समाधान खोज रहा था Map<String, Object>
, और कुछ भी नहीं मिला।
जिस तरह से मेरा yaml deserializer काम करता है, यह JSON ऑब्जेक्ट्स को Map<String, Object>
तब परिभाषित करता है जब आप एक प्रकार निर्दिष्ट नहीं करते हैं, लेकिन gson ऐसा नहीं करता है। सौभाग्य से आप इसे कस्टम डेज़राइज़र के साथ पूरा कर सकते हैं।
मैं स्वाभाविक रूप से deserialize कुछ भी करने के लिए निम्न deserializer इस्तेमाल किया, दोषी JsonObject
को रों Map<String, Object>
और JsonArray
करने के लिए रों Object[]
रों है, जहां सभी बच्चों इसी तरह deserialized कर रहे हैं।
private static class NaturalDeserializer implements JsonDeserializer<Object> {
public Object deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) {
if(json.isJsonNull()) return null;
else if(json.isJsonPrimitive()) return handlePrimitive(json.getAsJsonPrimitive());
else if(json.isJsonArray()) return handleArray(json.getAsJsonArray(), context);
else return handleObject(json.getAsJsonObject(), context);
}
private Object handlePrimitive(JsonPrimitive json) {
if(json.isBoolean())
return json.getAsBoolean();
else if(json.isString())
return json.getAsString();
else {
BigDecimal bigDec = json.getAsBigDecimal();
// Find out if it is an int type
try {
bigDec.toBigIntegerExact();
try { return bigDec.intValueExact(); }
catch(ArithmeticException e) {}
return bigDec.longValue();
} catch(ArithmeticException e) {}
// Just return it as a double
return bigDec.doubleValue();
}
}
private Object handleArray(JsonArray json, JsonDeserializationContext context) {
Object[] array = new Object[json.size()];
for(int i = 0; i < array.length; i++)
array[i] = context.deserialize(json.get(i), Object.class);
return array;
}
private Object handleObject(JsonObject json, JsonDeserializationContext context) {
Map<String, Object> map = new HashMap<String, Object>();
for(Map.Entry<String, JsonElement> entry : json.entrySet())
map.put(entry.getKey(), context.deserialize(entry.getValue(), Object.class));
return map;
}
}
handlePrimitive
विधि के अंदर की गड़बड़ी यह सुनिश्चित करने के लिए है कि आपको केवल एक डबल या एक इंटेगर या एक लॉन्ग प्राप्त हो, और संभवत: बेहतर हो, या कम से कम सरलीकृत हो सकता है यदि आप बिगडेकिमल प्राप्त करने के साथ ठीक हैं, जो मुझे लगता है कि डिफ़ॉल्ट है।
आप इस एडाप्टर को पंजीकृत कर सकते हैं जैसे:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Object.class, new NaturalDeserializer());
Gson gson = gsonBuilder.create();
और फिर इसे कॉल करें:
Object natural = gson.fromJson(source, Object.class);
मुझे यकीन नहीं है कि यह गन्स में डिफ़ॉल्ट व्यवहार क्यों नहीं है, क्योंकि यह अधिकांश अन्य अर्ध-संरचित क्रमांकन पुस्तकालयों में है ...
Map<String,Object> result = new Gson().fromJson(json, Map.class);
ग्सन 2.6.2 के साथ काम करता है।