Gson - Konvertiert von Json in eine typisierte ArrayList <T>

211

Wie konvertiere ich mithilfe der Gson-Bibliothek eine JSON-Zeichenfolge in ArrayListeine benutzerdefinierte Klasse JsonLog? Grundsätzlich JsonLogist eine Schnittstelle implementiert durch verschiedene Arten von Protokollen, die von meiner Android-App erstellt wurden - SMS-Protokolle, Anrufprotokolle, Datenprotokolle - und dies ArrayListist eine Sammlung von allen. Ich erhalte immer wieder einen Fehler in Zeile 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
    }
}

Es scheint, dass der Compiler nicht versteht, dass ich mich auf eine Eingabe beziehe ArrayList. Was mache ich?

Matthew Quiros
quelle
Bitte beachten Sie auch stackoverflow.com/questions/44589381/… für einen anderen Ansatz
Pankaj Jaiswal

Antworten:

515

Sie können TypeToken verwenden , um die JSON-Zeichenfolge in ein benutzerdefiniertes Objekt zu laden.

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

Dokumentation:

Repräsentiert einen generischen Typ T .

Java bietet noch keine Möglichkeit, generische Typen darzustellen, daher tut dies diese Klasse. Erzwingt, dass Clients eine Unterklasse dieser Klasse erstellen, mit der die Typinformationen auch zur Laufzeit abgerufen werden können.

Um beispielsweise ein Typliteral für zu erstellen List<String>, können Sie eine leere anonyme innere Klasse erstellen:

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

Diese Syntax kann nicht zum Erstellen von Typliteralen mit Platzhalterparametern wie Class<?>oder verwendet werden List<? extends CharSequence>.

Kotlin:

Wenn Sie es in Kotlin tun müssen, können Sie es so machen:

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

Oder Sie können diese Antwort für verschiedene Alternativen sehen.

Alex
quelle
3
Ich habe diesen Ansatz ausprobiert und einen Kompilierungsfehler erhalten, der besagt, dass TypeToken () nur den Zugriff geschützt hat
Jonathan
1
@ Jonney Ich habe das gleiche Problem. Irgendwelche Lösungen?
Zapnologica
15
wenn Sie bekommen haben Zugriffsfehler geschützt, links können Sie aus dem { }vor.getType()
Zapnologica
@Alex deserialisiert es zuerst in ein Array, dann wird dieses Array in List konvertiert, oder deserialisiert es direkt in List?
Adnan Ali
Ganz Kuh! Ich hätte gedacht, dass ... na ja ... niemals. Danke dir.
John Ward
26

Ihr JSON-Beispiel lautet:

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

Wenn Sie also eine Liste von Modulen in Ihren SharedPrefrences speichern möchten, gehen Sie wie folgt vor:

1- konvertiert Ihre zurückgegebene Arrayliste mit dieser Methode in das JSON-Format

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

2- Speichern Sie es in freigegebenen Voreinstellungen

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

3- Um es jederzeit abzurufen, rufen Sie JsonString aus solchen freigegebenen Einstellungen ab

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

4- Konvertieren Sie es erneut in eine Array-Liste

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

Diese Lösung ist auch möglich, wenn Sie die ArrayList of Objects analysieren möchten . Ich hoffe, sie hilft Ihnen bei der Verwendung der Gson Library .

Mohamed Hussien
quelle
Dies ist die richtige Lösung, aber im Wesentlichen die gleiche wie die drei Jahre ältere Antwort mit vielen unnötigen Informationen - ich bin nicht hierher gekommen, um mehr über sharedPreferences zu erfahren
Xerus
8

Wenn Sie Arrays verwenden möchten, ist dies ziemlich einfach.

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

Stellen Sie das JsonLogals Array bereitJsonLog[].class

Ali Asadi
quelle
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)

ODER

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

Warum hat niemand diese einfache Methode zum Konvertieren von JSON-Zeichenfolgen in List geschrieben ?

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

Ich bin mir bei gson nicht sicher, aber so machst du es mit Jon. Ich hoffe, es muss einen ähnlichen Weg geben, gson zu verwenden

{"Spieler": ["Spieler 1", "Spieler 2", "Spieler 3", "Spieler 4", "Spieler 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
quelle
@ Sagar Zala: Welches Beispiel erwartest du ..?
Arun Kongara
0

Du hast so einen String .

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

Dann können Sie es über Gson wie in ArrayList verdecken

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

Ihre HotelInfo- Klasse sollte dies mögen.

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
quelle