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?


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.


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 .


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


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)

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

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

@ 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
)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.