Estoy solicitando datos de un servidor que devuelve datos en formato JSON. Lanzar un HashMap en JSON al hacer la solicitud no fue difícil en absoluto, pero la otra forma parece ser un poco complicada. La respuesta JSON se ve así:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
¿De qué manera sería más fácil acceder a estos datos? Estoy usando el módulo GSON.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
funciona con gson 2.6.2.Respuestas:
Aqui tienes:
fuente
TypeToken
: hace un casting implícito dentro.{"k1":"apple","k2":"orange"}
Este código funciona:
fuente
Map<String, Object>
porque si el json no es solo cadenas, obtienes un errorTypeToken
.Sé que esta es una pregunta bastante antigua, pero estaba buscando una solución para deserializar genéricamente JSON anidado a a
Map<String, Object>
, y no encontré nada.De la forma en que funciona mi deserializador yaml, el valor predeterminado de los objetos JSON es
Map<String, Object>
cuando no especifica un tipo, pero gson no parece hacer esto. Afortunadamente, puedes lograrlo con un deserializador personalizado.He utilizado el siguiente deserializer de forma natural deserializar nada, el impago
JsonObject
s aMap<String, Object>
yJsonArray
s aObject[]
s, donde todos los niños se deserializan de manera similar.El desorden dentro del
handlePrimitive
método es para asegurarse de que solo obtenga un Doble o un Entero o un Largo, y probablemente podría ser mejor, o al menos simplificado si está de acuerdo con obtener BigDecimals, que creo que es el valor predeterminado.Puede registrar este adaptador como:
Y luego llámalo así:
No estoy seguro de por qué este no es el comportamiento predeterminado en gson, ya que está en la mayoría de las otras bibliotecas de serialización semiestructurada ...
fuente
Con Google's Gson 2.7 (probablemente también versiones anteriores, pero probé con la versión actual 2.7) es tan simple como:
Que devuelve un
Map
tipocom.google.gson.internal.LinkedTreeMap
y funciona de forma recursiva en objetos anidados, matrices, etc.Ejecuté el ejemplo de OP de esta manera (simplemente reemplacé el doble con comillas simples y eliminé el espacio en blanco):
Y obtuvo el siguiente resultado:
fuente
Actualización para la nueva lib de Gson:
ahora puede analizar Json anidado a Map directamente, pero debe tener en cuenta en caso de que intente analizar Json para
Map<String, Object>
escribir: generará una excepción. Para solucionar esto, simplemente declare el resultado comoLinkedTreeMap
tipo. Ejemplo a continuación:fuente
Map<String,Object> result = gson.fromJson(json , Map.class);
. Usando gson 2.6.2.Tenía exactamente la misma pregunta y terminé aquí. Tenía un enfoque diferente que parece mucho más simple (¿quizás versiones más nuevas de gson?).
con el siguiente json
El seguimiento
salidas
Puede verificar dinámicamente usando instanceof cuando navega por su jsonObject. Algo como
Funciona para mí, por lo que debe funcionar para usted ;-)
fuente
A continuación se admite desde gson 2.8.0
fuente
Prueba esto, funcionará. Lo usé para Hashtable .
Reemplace KioskStatusResource a su clase e Integer a su clase clave.
fuente
Esto es lo que he estado usando:
fuente
Aquí hay una frase que lo hará:
fuente
new TypeToken<HashMap<String, Object>>(){}
creará una nueva subclase en línea, y todas las listas generarán una advertencia al menos, supongoHe superado un problema similar con un JsonDeSerializer personalizado. Traté de hacerlo un poco genérico pero aún no lo suficiente. Sin embargo, es una solución que se adapta a mis necesidades.
En primer lugar, debe implementar un nuevo JsonDeserializer para objetos Map.
Y el método de deserialización se verá similar a esto:
La desventaja de esta solución es que la clave de mi Mapa siempre es de Tipo "Cadena". Sin embargo, al cambiar algunas cosas, alguien puede hacerlo genérico. Además, debo decir que la clase del valor debe pasarse en el constructor. Entonces, el método
getMyType()
en mi código devuelve el tipo de valores del Mapa, que se pasó en el constructor.Puedes hacer referencia a esta publicación ¿Cómo escribo un deserializador JSON personalizado para Gson? para aprender más sobre deserializadores personalizados.
fuente
Puede usar esta clase en su lugar :) (maneja incluso listas, listas anidadas y json)
Para convertir su cadena JSON a hashmap, use esto:
fuente
Esto es más una adición a la respuesta de Kevin Dolan que una respuesta completa, pero estaba teniendo problemas para extraer el tipo del Número. Esta es mi solución:
fuente
fuente
JSONObject generalmente usa
HashMap
internamente para almacenar los datos. Por lo tanto, puede usarlo como Mapa en su código.Ejemplo,
fuente
Usé este código:
fuente