Как я могу преобразовать JSON в хэш-карту с помощью Gson?
Я запрашиваю данные с сервера, который возвращает данные в формате JSON. Преобразование хэш-карты в JSON при выполнении запроса было совсем не сложным, но другой способ кажется немного сложнее. Ответ JSON выглядит следующим образом:
Я знаю, что это довольно старый вопрос, но я искал решение для общей десериализации вложенного JSON в Map<String, Object> и ничего не нашел.
То, как работает мой десериализатор yaml, по умолчанию для объектов JSON используется значение Map<String, Object>, когда вы не указываете тип, но gson, похоже, этого не делает. К счастью, вы можете выполнить это с помощью пользовательского десериализатора.
Я использовал следующий десериализатор для естественной десериализации чего угодно, по умолчанию заменив JsonObjects на Map<String, Object> и JsonArrays на Object[]s, где все дочерние элементы десериализуются аналогичным образом.
privatestaticclassNaturalDeserializerimplementsJsonDeserializer<Object> { public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { if(json.isJsonNull()) returnnull; elseif(json.isJsonPrimitive()) return handlePrimitive(json.getAsJsonPrimitive()); elseif(json.isJsonArray()) return handleArray(json.getAsJsonArray(), context); elsereturn handleObject(json.getAsJsonObject(), context); } private Object handlePrimitive(JsonPrimitive json) { if(json.isBoolean()) return json.getAsBoolean(); elseif(json.isString()) return json.getAsString(); else { BigDecimalbigDec= 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 = newObject[json.size()]; for(inti=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 = newHashMap<String, Object>(); for(Map.Entry<String, JsonElement> entry : json.entrySet()) map.put(entry.getKey(), context.deserialize(entry.getValue(), Object.class)); return map; } }
Сложность внутри handlePrimitive метода заключается в том, чтобы убедиться, что вы получаете только Double, целое число или Long, и, вероятно, могло бы быть лучше или, по крайней мере, упрощено, если вы согласны с получением BigDecimals, которые, как я полагаю, используются по умолчанию.
Вы можете зарегистрировать этот адаптер следующим образом: