Gson - converte de Json em um ArrayList <T> digitado

211

Usando a biblioteca Gson, como faço para converter uma string JSON em uma ArrayListclasse personalizada JsonLog? Basicamente, JsonLogé uma interface implementada por diferentes tipos de logs criados pelo meu aplicativo Android - logs de SMS, logs de chamadas, logs de dados - e essa ArrayListé uma coleção de todos eles. Continuo recebendo um erro na linha 6.

public static void log(File destination, JsonLog log) {
    Collection<JsonLog> logs = null;
    if (destination.exists()) {
        Gson gson = new Gson();
        BufferedReader br = new BufferedReader(new FileReader(destination));
        logs = gson.fromJson(br, ArrayList<JsonLog>.class); // line 6
        // logs.add(log);
        // serialize "logs" again
    }
}

Parece que o compilador não entende que estou me referindo a um tipo ArrayList. O que eu faço?

Matthew Quiros
fonte
Consulte também stackoverflow.com/questions/44589381/… para outra abordagem #
Pankaj Jaiswal

Respostas:

515

Você pode usar o TypeToken para carregar a sequência json em um objeto personalizado.

logs = gson.fromJson(br, new TypeToken<List<JsonLog>>(){}.getType());

Documentação:

Representa um tipo genérico T .

Java ainda não fornece uma maneira de representar tipos genéricos, então essa classe fornece. Força os clientes a criar uma subclasse dessa classe que permite recuperar as informações de tipo, mesmo em tempo de execução.

Por exemplo, para criar um literal de tipo List<String>, você pode criar uma classe interna anônima vazia:

TypeToken<List<String>> list = new TypeToken<List<String>>() {};

Essa sintaxe não pode ser usada para criar literais de tipo que possuem parâmetros curinga, como Class<?>ou List<? extends CharSequence>.

Kotlin:

Se você precisar fazer isso no Kotlin, faça o seguinte:

val myType = object : TypeToken<List<JsonLong>>() {}.type
val logs = gson.fromJson<List<JsonLong>>(br, myType)

Ou você pode ver esta resposta para várias alternativas.

Alex
fonte
3
tentou essa abordagem e eu tenho um erro de compilação dizendo TypeToken () tem protegido o acesso somente
Jonathan
1
@ Jonney Eu tenho o mesmo problema. Alguma solução?
Zapnologica
15
se você está recebendo tem protegido erro de acesso, você deixou de fora a { }antes.getType()
Zapnologica
@Alex desserializa primeiro para uma matriz e depois a matriz é convertida em lista ou diretamente desserializada para lista?
Adnan Ali
Totalmente vaca! Eu teria imaginado isso como ... bem ... nunca. Obrigado.
John Ward
26

Sua amostra JSON é:

{
    "status": "ok",
    "comment": "",
    "result": {
    "id": 276,
    "firstName": "mohamed",
    "lastName": "hussien",
    "players": [
            "player 1",
            "player 2",
            "player 3",
            "player 4",
            "player 5"
    ]
}

então, se você deseja salvar a lista de módulos dos módulos em suas SharedPrefrences, então:

1- converterá sua lista de matriz retornada para o formato json usando este método

public static String toJson(Object jsonObject) {
    return new Gson().toJson(jsonObject);
}

2- Salve-o em prefreneces compartilhados

PreferencesUtils.getInstance(context).setString("players", toJson((.....ArrayList you want to convert.....)));

3- para recuperá-lo a qualquer momento, obtenha o JsonString de Preferências compartilhadas como essa

String playersString= PreferencesUtils.getInstance(this).getString("players");

4- converta-o novamente para a lista de arrays

public static Object fromJson(String jsonString, Type type) {
    return new Gson().fromJson(jsonString, type);
}

ArrayList<String> playersList= (ArrayList<String>) fromJson(playersString,
                    new TypeToken<ArrayList<String>>() {
                    }.getType());

Essa solução também é possível se você deseja analisar o ArrayList of Objects. Espero que seja útil usando a Biblioteca Gson .

Mohamed Hussien
fonte
esta é a solução correta, mas essencialmente o mesmo que os três anos resposta mais velha com um monte de informações unneccessary - Eu não vim aqui para aprender sobre SharedPreferences
Xerus
8

Se você deseja usar Arrays, é bem simples.

logs = gson.fromJson(br, JsonLog[].class); // line 6

Forneça o JsonLogcomo uma matrizJsonLog[].class

Ali Asadi
fonte
8

Kotlin

data class Player(val name : String, val surname: String)

val json = [
  {
    "name": "name 1",
    "surname": "surname 1"
  },
  {
    "name": "name 2",
    "surname": "surname 2"
  },
  {
    "name": "name 3",
    "surname": "surname 3"
  }
]

val typeToken = object : TypeToken<List<Player>>() {}.type
val playerArray = Gson().fromJson<List<Player>>(json, typeToken)

OU

val playerArray = Gson().fromJson(json, Array<Player>::class.java)
murgupluoglu
fonte
5

Por que ninguém escreveu essa maneira simples de converter a string JSON na lista ?

List<Object> list = Arrays.asList(new GsonBuilder().create().fromJson(jsonString, Object[].class));
FarukT
fonte
1

Eu não tenho certeza sobre o gson, mas é assim que você faz isso com Jon.

{"Jogadores": ["jogador 1", "jogador 2", "jogador 3", "jogador 4", "jogador 5"]}

=================================================

import java.io.FileReader;
import java.util.List;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class JosnFileDemo {

    public static void main(String[] args) throws Exception
    {
        String jsonfile ="fileloaction/fileName.json";


                FileReader reader = null;
                JSONObject jsb = null;
                try {
                    reader = new FileReader(jsonfile);
                    JSONParser jsonParser = new JSONParser();
                     jsb = (JSONObject) jsonParser.parse(reader);
                } catch (Exception e) {
                    throw new Exception(e);
                } finally {
                    if (reader != null)
                        reader.close();
                }
                List<String> Players=(List<String>) jsb.get("Players");
                for (String player : Players) {
                    System.out.println(player);
                }           
    }
}
arun kongara
fonte
@ Sagar Zala: qual é o exemplo que você está esperando ..?
Arun kongara
0

Você tem uma string como esta.

"[{"id":2550,"cityName":"Langkawi","hotelName":"favehotel Cenang Beach - Langkawi","hotelId":"H1266070"},
{"id":2551,"cityName":"Kuala Lumpur","hotelName":"Metro Hotel Bukit Bintang","hotelId":"H835758"}]"

Em seguida, você pode enviá-lo para ArrayList via Gson, como

var hotels = Gson().fromJson(historyItem.hotels, Array<HotelInfo>::class.java).toList()

Sua classe HotelInfo deve ser assim.

import com.squareup.moshi.Json

data class HotelInfo(

    @Json(name="cityName")
    val cityName: String? = null,

    @Json(name="id")
    val id: Int? = null,

    @Json(name="hotelId")
    val hotelId: String? = null,

    @Json(name="hotelName")
    val hotelName: String? = null
)
Shihab Uddin
fonte