Gson - converte da Json in una ArrayList tipizzata <T>


211

Utilizzando la libreria Gson, come posso convertire una stringa JSON in una ArrayListdi una classe personalizzata JsonLog? Fondamentalmente, JsonLogè un'interfaccia implementata da diversi tipi di registri creati dalla mia app Android - registri SMS, registri delle chiamate, registri dati - e questa ArrayListè una raccolta di tutti loro. Continuo a ricevere un errore nella riga 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
    }
}

Sembra che il compilatore non capisca che mi riferisco a un tipo ArrayList. Cosa faccio?


Fare riferimento anche a stackoverflow.com/questions/44589381/… per un altro approccio
Pankaj Jaiswal,

Risposte:


516

È possibile utilizzare TypeToken per caricare la stringa JSON in un oggetto personalizzato.

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

Documentazione:

Rappresenta un tipo generico T .

Java non fornisce ancora un modo per rappresentare tipi generici, quindi questa classe lo fa. Forza i client a creare una sottoclasse di questa classe che consenta di recuperare le informazioni sul tipo anche in fase di esecuzione.

Ad esempio, per creare un tipo letterale per List<String>, è possibile creare una classe interna anonima vuota:

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

Questa sintassi non può essere utilizzata per creare letterali di tipo con parametri jolly, come Class<?>o List<? extends CharSequence>.

Kotlin:

Se hai bisogno di farlo in Kotlin puoi farlo in questo modo:

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

Oppure puoi vedere questa risposta per varie alternative.


3
ho provato questo approccio e ho ricevuto un errore di compilazione dicendo che TypeToken () ha protetto solo l'accesso
Jonathan

1
@jonney Ho lo stesso problema. Qualche soluzione?
Zapnologica,

15
se stai ricevendo un errore di accesso protetto, hai lasciato fuori il { }precedente.getType()
Zapnologica

@Alex deserializza prima in un array, quindi l'array viene convertito in elenco o deserializza direttamente in elenco?
Adnan Ali,

Completamente mucca! Lo avrei immaginato come ... beh ... mai. Grazie.
John Ward,

26

Il tuo esempio JSON è:

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

quindi se vuoi salvare l'arraylist dei moduli nei tuoi SharedPrefrences così:

1- convertirà il tuo array restituito per il formato json usando questo metodo

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

2- Salvalo in prefreneces condivisi

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

3- per recuperarlo in qualsiasi momento ottenere JsonString da Preferenze condivise del genere

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

4- convertirlo di nuovo in elenco array

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());

questa soluzione è realizzabile anche se si desidera analizzare ArrayList of Objects Spero che sia di aiuto utilizzando Gson Library .


questa è la soluzione corretta, ma essenzialmente la stessa della risposta di tre anni con molte informazioni non necessarie - Non sono venuto qui per conoscere le preferenze condivise
Xerus

8

Se vuoi usare gli array, è piuttosto semplice.

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

Fornire JsonLogcome arrayJsonLog[].class


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)

O

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

5

Perché nessuno ha scritto questo semplice modo di convertire la stringa JSON in List ?

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

1

Non sono sicuro di GSON, ma è così che lo fai con Jon. Spero che ci debba essere un modo simile usando Gson

{"Giocatori": ["giocatore 1", "giocatore 2", "giocatore 3", "giocatore 4", "giocatore 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);
                }           
    }
}

@ Sagar Zala: quale esempio ti aspetti ..?
Arun Kongong,

0

Hai una stringa come questa.

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

Quindi puoi convertirlo in ArrayList tramite Gson come

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

La tua classe HotelInfo dovrebbe gradire questo.

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
)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.