Converter JSON em um mapa usando o Gson
1. Introdução
In this quick tutorial, we’ll learn how to convert a JSON string to a Map using Gson from Google.
Veremos três abordagens diferentes para fazer isso e discutiremos seus prós e contras - com alguns exemplos práticos.
2. AprovandoMap.class
Em geral,Gson provides the following API in its Gson class to convert a JSON string to an object:
public T fromJson(String json, Class classOfT) throws JsonSyntaxException;
A partir da assinatura, fica muito claro que o segundo parâmetro é a classe do objeto que pretendemos que o JSON analise. Em nosso caso, deve serMap.class:
String jsonString = "{'employee.name':'Bob','employee.salary':10000}";
Gson gson = new Gson();
Map map = gson.fromJson(jsonString, Map.class);
Assert.assertEquals(2, map.size());
Assert.assertEquals(Double.class, map.get("employee.salary").getClass());
Essa abordagem fará sua melhor estimativa em relação ao tipo de valor para cada propriedade.
Por exemplo, os números serão coagidos emDoubles,true areiafalse emBoolean e os objetos emLinkedTreeMaps.
Se houver chaves duplicadas, porém, a coerção falhará e lançará umJsonSyntaxException.
E, devido atype erasure,, também não poderemos configurar este comportamento de coerção. Portanto, se precisarmos especificar os tipos de chave ou valor, precisaremos de uma abordagem diferente.
3. UsandoTypeToken
To overcome the problem of type-erasure for the generic types, Gson has an overloaded version of the API:
public T fromJson(String json, Type typeOfT) throws JsonSyntaxException;
Podemos construir umMap com seus parâmetros de tipo usandoTypeToken de Gson. The TypeToken class returns an instance of ParameterizedTypeImpl that preserves the type of the key and value even at runtime:
String jsonString = "{'Bob' : {'name': 'Bob Willis'},"
+ "'Jenny' : {'name': 'Jenny McCarthy'}, "
+ "'Steve' : {'name': 'Steven Waugh'}}";
Gson gson = new Gson();
Type empMapType = new TypeToken
Agora, se construirmos nosso tipoMap comoMap<String, Object>, o analisador ainda será o padrão, como vimos na seção anterior.
Obviamente, isso ainda se aplica a Gson por coagir tipos primitivos. Esses, no entanto, também podem ser personalizados.
4. UsandoJsonDeserializer personalizado
Quando precisamos de controle refinado sobre a construção de nosso objetoMap, podemos implementar um desserializador personalizado do tipoJsonDeserializer<Map>.
Para ver um exemplo, vamos supor que nosso JSON contenha o nome do funcionário como chave e a data de contratação como valor. Além disso, vamos assumir que o formato da data éyyyy/MM/dd, que não é um formato padrão paraGson.
Podemos configurar o Gson para analisar nosso mapa de maneira diferente, então, implementando umJsonDeserializer:
public class StringDateMapDeserializer implements JsonDeserializer
Agora, temos que registrá-lo emGsonBuilder contra nosso tipo de destinoMap<String, Date> e construir um objetoGson personalizado.
Quando chamamos a APIfromJson neste objetoGson, o analisador invoca o desserializador personalizado e retorna a instânciaMap desejada:
String jsonString = "{'Bob': '2017-06-01', 'Jennie':'2015-01-03'}";
Type type = new TypeToken
Essa tática também é útil quando nosso mapa pode conter valores heterogêneos e temos uma boa idéia de quantos tipos diferentes de valores podem estar lá.
Para saber mais sobre um desserializador personalizado emGson, sinta-se à vontade para passar porGson Deserialization Cookbook.
5. Conclusão
Neste breve artigo, aprendemos várias maneiras de construir um mapa a partir de uma string formatada em JSON. E também discutimos casos de uso adequados para essas variações.
O código-fonte dos exemplos está disponívelover on GitHub.