나는 이것이 상당히 오래된 질문이라는 것을 알고 있지만 중첩 된 JSON을 a로 직렬화 해제하는 솔루션을 찾고 있었고 Map<String, Object>
아무것도 찾지 못했습니다.
내 yaml deserializer가 작동 Map<String, Object>
하는 방식으로 유형을 지정하지 않으면 JSON 객체가 기본으로 설정되지만 gson 은이 작업을 수행하지 않는 것 같습니다. 다행히 사용자 지정 디시리얼라이저를 사용하여이 작업을 수행 할 수 있습니다.
나는 다음 deserializer를 사용하여 모든 자식을 비슷하게 deserialize하는 기본적으로 JsonObject
s Map<String, Object>
와 JsonArray
s를 기본값으로 Object[]
deserialize했습니다.
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
방법 의 혼란 은 Double 또는 Integer 또는 Long 만 얻도록하는 것입니다. BigDecimals를 얻는 것이 괜찮다면 더 좋거나 최소한 단순화 될 수 있습니다. 이것이 기본값이라고 생각합니다.
다음과 같이이 어댑터를 등록 할 수 있습니다.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Object.class, new NaturalDeserializer());
Gson gson = gsonBuilder.create();
그리고 다음과 같이 호출하십시오.
Object natural = gson.fromJson(source, Object.class);
이것이 대부분의 다른 반 구조화 직렬화 라이브러리에 있기 때문에 왜 이것이 gson의 기본 동작이 아닌지 잘 모르겠습니다 ...
Map<String,Object> result = new Gson().fromJson(json, Map.class);
gson 2.6.2에서 작동합니다.