Estou solicitando dados de um servidor que retorna dados no formato JSON. A conversão de um HashMap no JSON ao fazer a solicitação não foi difícil, mas a outra maneira parece um pouco complicada. A resposta JSON é assim:
{
"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 que maneira seria mais fácil acessar esses dados? Estou usando o módulo GSON.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
trabalha com o gson 2.6.2.Respostas:
Aqui está:
fonte
TypeToken
- ele faz a conversão implícita por dentro.{"k1":"apple","k2":"orange"}
Este código funciona:
fonte
Map<String, Object>
porque se o JSON não é apenas cordas você receber um erroTypeToken
.Sei que essa é uma pergunta bastante antiga, mas estava procurando uma solução para desserializar genericamente JSON aninhado para um
Map<String, Object>
e não encontrei nada.Da forma como meu desserializador yaml funciona, ele padroniza os objetos JSON para
Map<String, Object>
quando você não especifica um tipo, mas o gson não parece fazer isso. Felizmente, você pode fazer isso com um desserializador personalizado.Eu usei o seguinte desserializador para naturalmente deserialize nada, inadimplente
JsonObject
s aMap<String, Object>
eJsonArray
s aObject[]
s, onde todas as crianças são igualmente desserializados.A bagunça dentro do
handlePrimitive
método é garantir que você só receba um Duplo, um Inteiro ou um Longo, e provavelmente poderia ser melhor, ou pelo menos simplificado, se você estiver satisfeito com o BigDecimals, que eu acredito que seja o padrão.Você pode registrar este adaptador como:
E então chame assim:
Não sei por que esse não é o comportamento padrão no gson, pois está na maioria das outras bibliotecas de serialização semiestruturadas ...
fonte
Com o Gson 2.7 do google (provavelmente versões anteriores também, mas eu testei com a versão atual 2.7), é tão simples quanto:
Que retorna um
Map
tipocom.google.gson.internal.LinkedTreeMap
e funciona recursivamente em objetos aninhados, matrizes etc.Executei o exemplo do OP da seguinte maneira (basta substituir as aspas simples por aspas simples e remover o espaço em branco):
E obteve a seguinte saída:
fonte
Atualização para a nova lib do Gson:
Agora você pode analisar o Json aninhado diretamente no Map, mas você deve estar ciente de que, caso tente analisar o Json para
Map<String, Object>
digitar: isso gerará uma exceção. Para corrigir isso, basta declarar o resultado comoLinkedTreeMap
tipo. Exemplo abaixo:fonte
Map<String,Object> result = gson.fromJson(json , Map.class);
. Usando o gson 2.6.2.Eu tinha exatamente a mesma pergunta e acabei aqui. Eu tive uma abordagem diferente que parece muito mais simples (talvez versões mais recentes do gson?).
com o seguinte json
Os seguintes
saídas
Você pode verificar dinamicamente usando instanceof ao navegar no jsonObject. Algo como
Funciona para mim, então deve funcionar para você ;-)
fonte
Abaixo é suportado desde o gson 2.8.0
fonte
Tente isso, vai funcionar. Eu usei para Hashtable .
Substitua KioskStatusResource na sua classe e Inteiro na sua classe-chave.
fonte
Aqui está o que eu tenho usado:
fonte
Aqui está uma lista que fará isso:
fonte
new TypeToken<HashMap<String, Object>>(){}
criará uma nova subclasse em linha, e todos osEu superei um problema semelhante com um JsonDeSerializer personalizado. Tentei torná-lo um pouco genérico, mas ainda não o suficiente. É uma solução que atenda às minhas necessidades.
Antes de tudo, você precisa implementar um novo JsonDeserializer para objetos de mapa.
E o método desserialize será semelhante a este:
O problema dessa solução é que a chave do meu mapa é sempre do tipo "String". No entanto, perseguindo algumas coisas, alguém pode torná-lo genérico. Além disso, eu preciso dizer que a classe do valor deve ser passada no construtor. Portanto, o método
getMyType()
no meu código retorna o tipo dos valores do mapa, que foram passados no construtor.Você pode consultar esta postagem Como eu escrevo um desserializador JSON personalizado para o Gson? para saber mais sobre desserializadores personalizados.
fonte
Em vez disso, você pode usar esta classe :) (lida com listas pares, listas aninhadas e json)
Para converter sua string JSON em hashmap, use este:
fonte
Isso é mais um adendo à resposta de Kevin Dolan do que uma resposta completa, mas eu estava tendo problemas para extrair o tipo do Número. Esta é a minha solução:
fonte
fonte
JSONObject normalmente usa
HashMap
internamente para armazenar os dados. Portanto, você pode usá-lo como mapa no seu código.Exemplo,
fonte
Eu usei este código:
fonte