Gson - convertir de Json en une liste de tableaux typée <T>

211

À l'aide de la bibliothèque Gson, comment convertir une chaîne JSON en une ArrayListclasse personnalisée JsonLog? Fondamentalement, JsonLogest une interface implémentée par différents types de journaux créés par mon application Android - journaux SMS, journaux d'appels, journaux de données - et celaArrayList c'est une collection de tous. Je reçois toujours une erreur à la ligne 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
    }
}

Il semble que le compilateur ne comprenne pas que je fais référence à un type ArrayList. Que fais-je?

Matthew Quiros
la source
Veuillez également vous référer à stackoverflow.com/questions/44589381/… pour une autre approche
Pankaj Jaiswal

Réponses:

516

Vous pouvez utiliser TypeToken pour charger la chaîne json dans un objet personnalisé.

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

Documentation:

Représente un type générique T .

Java ne fournit pas encore de moyen de représenter les types génériques, donc cette classe le fait. Force les clients à créer une sous-classe de cette classe qui permet de récupérer les informations de type même à l'exécution.

Par exemple, pour créer un littéral de type pour List<String>, vous pouvez créer une classe interne anonyme vide:

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

Cette syntaxe ne peut pas être utilisée pour créer des littéraux de type qui ont des paramètres génériques, tels que Class<?>ou List<? extends CharSequence>.

Kotlin:

Si vous devez le faire dans Kotlin, vous pouvez le faire comme ceci:

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

Ou vous pouvez voir cette réponse pour différentes alternatives.

Alex
la source
3
essayé cette approche et j'ai eu une erreur de compilation disant que TypeToken () a protégé l'accès uniquement
Jonathan
1
@jonney J'ai le même problème. Des solutions?
Zapnologica
15
si vous obtenez une erreur d'accès protégé, vous avez laissé de côté { }avant.getType()
Zapnologica
@Alex désérialise-t-il d'abord en tableau puis ce tableau est converti en liste ou désérialise-t-il directement en liste?
Adnan Ali
Entièrement vache! J'aurais pensé ça comme ... eh bien ... jamais. Je vous remercie.
John Ward
26

Votre échantillon JSON est:

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

donc si vous voulez enregistrer une liste de modules dans vos SharedPrefrences:

1- convertira votre liste d'arrays retournée au format json en utilisant cette méthode

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

2- Enregistrez-le dans des pré-recréations partagées

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

3- Pour le récupérer à tout moment, obtenez JsonString à partir des préférences partagées comme ça

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

4- Convertissez-le à nouveau en liste de tableaux

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

cette solution est également réalisable si vous souhaitez analyser ArrayList of Objects J'espère que cela vous aidera en utilisant Gson Library .

Mohamed Hussien
la source
c'est la bonne solution, mais essentiellement la même que la réponse de trois ans avec beaucoup d'informations inutiles - je ne suis pas venu ici pour en savoir plus sur les préférences partagées
Xerus
8

Si vous souhaitez utiliser des tableaux, c'est assez simple.

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

Fournir le JsonLogsous forme de tableauJsonLog[].class

Ali Asadi
la source
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
la source
5

Pourquoi personne n'a écrit cette manière simple de convertir une chaîne JSON dans List ?

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

Je ne suis pas sûr de gson mais c'est comme ça que vous le faites avec Jon.sample j'espère qu'il doit y avoir une manière similaire d'utiliser gson

{"Joueurs": ["joueur 1", "joueur 2", "joueur 3", "joueur 4", "joueur 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
la source
@ Sagar Zala: quel exemple attendez-vous ..?
arun kongara
0

Vous avez une chaîne comme celle-ci.

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

Ensuite, vous pouvez le convertir en ArrayList via Gson comme

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

Votre classe HotelInfo devrait aimer cela.

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
la source