So analysieren Sie JSON-Arrays mit Gson


83

Ich möchte JSON-Arrays analysieren und gson verwenden. Erstens kann ich die JSON-Ausgabe protokollieren, der Server reagiert eindeutig auf den Client.

Hier ist meine JSON-Ausgabe:

 [
      {
           id : '1',
           title: 'sample title',
           ....
      },
      {
           id : '2',
           title: 'sample title',
           ....
     },
      ...
 ]

Ich habe diese Struktur zum Parsen ausprobiert. Eine Klasse, die von Single arrayund ArrayListfür alle JSONArray abhängt.

 public class PostEntity {

      private ArrayList<Post> postList = new ArrayList<Post>();

      public List<Post> getPostList() { 
           return postList; 
      }

      public void setPostList(List<Post> postList) { 
           this.postList = (ArrayList<Post>)postList; 
      } 
 }

Postklasse:

 public class Post {

      private String id;
      private String title;

      /* getters & setters */
 }

Wenn ich versuche, gson zu verwenden, kein Fehler, keine Warnung und kein Protokoll:

 GsonBuilder gsonb = new GsonBuilder();
 Gson gson = gsonb.create();

 PostEntity postEnt;
 JSONObject jsonObj = new JSONObject(jsonOutput);
 postEnt = gson.fromJson(jsonObj.toString(), PostEntity.class);

 Log.d("postLog", postEnt.getPostList().get(0).getId());

Was ist los, wie kann ich lösen?

Antworten:


243

Sie können das JSONArraydirekt analysieren , müssen Ihre PostKlasse nicht noch einmal umbrechen PostEntityund benötigen auch kein neues JSONObject().toString():

Gson gson = new Gson();
String jsonOutput = "Your JSON String";
Type listType = new TypeToken<List<Post>>(){}.getType();
List<Post> posts = gson.fromJson(jsonOutput, listType);

Hoffentlich hilft das.


Ich habe die PostEntity-Klasse gelöscht und stattdessen Ihr Snippet ausprobiert. Immer noch keine Veränderung. Vielen Dank.
Ogulcan Orhan

Endlich richtig und effizient gearbeitet. Nochmal vielen Dank.
Ogulcan Orhan

Hallo, wie man verschachtelte JSON-Array-Daten wie folgt analysiert ... [{"Vorname": "Bidhan", "Nachname": "Chatterjee"}, [{"Typ": "Persönlich", "Nummer": "09832209761" }, {"type": "fax", "number": "91-342-2567692"}]]
KK_07k11A0585

Gibt es einen Vorteil bei der Verwendung von TypeToken? Aus meinen Tests geht hervor, dass gson ein List <Object> -Feld ohne TypeToken verarbeitet.
Greg7gkb

Dies ist wirklich hilfreich für mich
Bhavesh Kaila

6

Ich suchte nach einer Möglichkeit, Objektarrays allgemeiner zu analysieren. Hier ist mein Beitrag:

CollectionDeserializer.java::

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class CollectionDeserializer implements JsonDeserializer<Collection<?>> {

    @Override
    public Collection<?> deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
        Type realType = ((ParameterizedType)typeOfT).getActualTypeArguments()[0];

        return parseAsArrayList(json, realType);
    }

    /**
     * @param serializedData
     * @param type
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> ArrayList<T> parseAsArrayList(JsonElement json, T type) {
        ArrayList<T> newArray = new ArrayList<T>();
        Gson gson = new Gson();

        JsonArray array= json.getAsJsonArray();
        Iterator<JsonElement> iterator = array.iterator();

        while(iterator.hasNext()){
            JsonElement json2 = (JsonElement)iterator.next();
            T object = (T) gson.fromJson(json2, (Class<?>)type);
            newArray.add(object);
        }

        return newArray;
    }

}

JSONParsingTest.java::

public class JSONParsingTest {

    List<World> worlds;

    @Test
    public void grantThatDeserializerWorksAndParseObjectArrays(){

        String worldAsString = "{\"worlds\": [" +
            "{\"name\":\"name1\",\"id\":1}," +
            "{\"name\":\"name2\",\"id\":2}," +
            "{\"name\":\"name3\",\"id\":3}" +
        "]}";

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Collection.class, new CollectionDeserializer());
        Gson gson = builder.create();
        Object decoded = gson.fromJson((String)worldAsString, JSONParsingTest.class);

        assertNotNull(decoded);
        assertTrue(JSONParsingTest.class.isInstance(decoded));

        JSONParsingTest decodedObject = (JSONParsingTest)decoded;
        assertEquals(3, decodedObject.worlds.size());
        assertEquals((Long)2L, decodedObject.worlds.get(1).getId());
    }
}

World.java::

public class World {
    private String name;
    private Long id;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

@Miere Ich verstehe nicht, wie dies von JsonArray in List <World>
ARK

Grundsätzlich wird der CollectionDeserializer für jede Sammlung verwendet, die während des GSON-Deserialisierungsprozesses gefunden wurde. CollectionDeserializer leitet seinerseits durch den generischen Parameter der Sammlung, welche Klasse den Objektspeicher in der Sammlung darstellt, die deserialisiert werden soll. Ich hoffe das hat deine Frage beantwortet. Wenn Sie immer noch Zweifel haben, kontaktieren Sie mich bitte unter [miere00 at gmail.com].
Miere

Hallo @Miere, diese Lösung behandelt die ursprüngliche Frage nicht. Ihr JSONParsingTest ist ein Objekt mit einem darin enthaltenen Array. Wie verwenden Sie Ihren CollectionDeserializer, um nur ein Array zu analysieren, nicht ein in ein Objekt eingeschlossenes Array?
Zkon

5

Konvertieren in Object Array

Gson gson=new Gson();
ElementType [] refVar=gson.fromJson(jsonString,ElementType[].class);

Als Beitragstyp konvertieren

Gson gson=new Gson();
Post [] refVar=gson.fromJson(jsonString,Post[].class);

Um es als Liste der Objekte zu lesen, kann TypeToken verwendet werden

List<Post> posts=(List<Post>)gson.fromJson(jsonString, 
                     new TypeToken<List<Post>>(){}.getType());

Wie wäre es als ArrayList <Post>?
Gumuruh

3

Einige der Antworten in diesem Beitrag sind gültig. Mit TypeToken generiert die Gson-Bibliothek jedoch Baumobjekte mit unwirklichen Typen für Ihre Anwendung.

Um es zu bekommen, musste ich das Array lesen und die Objekte innerhalb des Arrays nacheinander konvertieren. Natürlich ist diese Methode nicht die schnellste und ich empfehle nicht, sie zu verwenden, wenn das Array zu groß ist, aber es hat bei mir funktioniert.

Es ist erforderlich, die Json-Bibliothek in das Projekt aufzunehmen. Wenn Sie auf Android entwickeln, ist es enthalten:

/**
 * Convert JSON string to a list of objects
 * @param sJson String sJson to be converted
 * @param tClass Class
 * @return List<T> list of objects generated or null if there was an error
 */
public static <T> List<T> convertFromJsonArray(String sJson, Class<T> tClass){

    try{
        Gson gson = new Gson();
        List<T> listObjects = new ArrayList<>();

        //read each object of array with Json library
        JSONArray jsonArray = new JSONArray(sJson);
        for(int i=0; i<jsonArray.length(); i++){

            //get the object
            JSONObject jsonObject = jsonArray.getJSONObject(i);

            //get string of object from Json library to convert it to real object with Gson library
            listObjects.add(gson.fromJson(jsonObject.toString(), tClass));
        }

        //return list with all generated objects
        return listObjects;

    }catch(Exception e){
        e.printStackTrace();
    }

    //error: return null
    return null;
}

3
[
      {
           id : '1',
           title: 'sample title',
           ....
      },
      {
           id : '2',
           title: 'sample title',
           ....
     },
      ...
 ]

Überprüfen Sie den Easy-Code für diese Ausgabe

 Gson gson=new GsonBuilder().create();
                List<Post> list= Arrays.asList(gson.fromJson(yourResponse.toString,Post[].class));

2
Type listType = new TypeToken<List<Post>>() {}.getType();
List<Post> posts = new Gson().fromJson(jsonOutput.toString(), listType);

6
Dies kann zwar die Frage beantworten, bietet jedoch keinen Kontext, um zu erklären, wie oder warum. Fügen Sie ein oder zwei Sätze hinzu, um Ihre Antwort zu erklären.
Brandonscript

1

Sie können dies in Kotlin einfach mit dem folgenden Code tun:

val fileData = "your_json_string"
val gson = GsonBuilder().create()
val packagesArray = gson.fromJson(fileData , Array<YourClass>::class.java).toList()

Grundsätzlich müssen Sie nur eine bieten Arrayvon YourClassObjekten.


Warum verwenden Sie PrettyPrinting?
Antroid

@antroid Ich habe vergessen, es zu entfernen ^^
xarlymg89

0

Sie können den Listenwert abrufen, ohne das Type- Objekt zu verwenden.

EvalClassName[] evalClassName;
ArrayList<EvalClassName> list;
evalClassName= new Gson().fromJson(JSONArrayValue.toString(),EvalClassName[].class);
list = new ArrayList<>(Arrays.asList(evalClassName));

Ich habe es getestet und es funktioniert.

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.