Come analizzare array JSON con Gson


86

Voglio analizzare gli array JSON e usare gson. In primo luogo, posso registrare l'output JSON, il server risponde chiaramente al client.

Ecco il mio output JSON:

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

Ho provato questa struttura per l'analisi. Una classe, che dipende dal singolo arraye ArrayListper tutti JSONArray.

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

Post class:

 public class Post {

      private String id;
      private String title;

      /* getters & setters */
 }

Quando provo a usare gson nessun errore, nessun avviso e nessun registro:

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

Cosa c'è che non va, come posso risolvere?

Risposte:


251

Puoi analizzare JSONArraydirettamente, non è necessario concludere la Postlezione con PostEntityun'altra volta e non è necessario JSONObject().toString()nemmeno nuovo :

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

Spero possa aiutare.


Ho eliminato la classe PostEntity e ho provato invece il tuo snippet. Ancora nessun cambiamento. Grazie.
Ogulcan Orhan

Finalmente ha funzionato correttamente ed efficacemente. Grazie mille ancora.
Ogulcan Orhan

Salve, come analizzare i dati dell'array json nidificati in questo modo .... [{"firstName": "Bidhan", "lastName": "Chatterjee"}, [{"type": "personal", "number": "09832209761" }, {"type": "fax", "number": "91-342-2567692"}]]
KK_07k11A0585

C'è un vantaggio nell'usare TypeToken? Dai miei test, gson sembra gestire un campo List <Object> senza utilizzare TypeToken.
greg7gkb

Questo è davvero utile per me
bhavesh kaila

6

Stavo cercando un modo per analizzare gli array di oggetti in un modo più generico; ecco il mio contributo:

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 Non capisco come questo converte da JsonArray a List <World>
ARK

Fondamentalmente, utilizza CollectionDeserializer per ogni raccolta trovata durante il processo di deserializzazione GSON. CollectionDeserializer a sua volta deduce tramite il parametro generico della Collection quale classe rappresenta l'archivio oggetti della raccolta che deve deserializzare. Spero che questo abbia risposto alla tua domanda. Se hai ancora dubbi, contattami a [miere00 at gmail.com].
Miere

Ciao @Miere, questa soluzione non gestisce la domanda originale. Il tuo JSONParsingTest è un oggetto con un array all'interno. Come si utilizza CollectionDeserializer per analizzare solo un array, non un array racchiuso in un oggetto?
zkon

5

Per convergere in Object Array

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

Per convertire come tipo di post

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

Per leggerlo come Elenco di oggetti è possibile utilizzare TypeToken

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

che ne dici di ArrayList <Post>?
gumuruh

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

6
Sebbene questo possa rispondere alla domanda, non fornisce alcun contesto per spiegare come o perché. Considera l'idea di aggiungere una o due frasi per spiegare la tua risposta.
brandonscript,

3

Alcune delle risposte di questo post sono valide, ma utilizzando TypeToken, la libreria Gson genera oggetti Tree con tipi irreali per la tua applicazione.

Per ottenerlo ho dovuto leggere l'array e convertire uno per uno gli oggetti all'interno dell'array. Ovviamente questo metodo non è il più veloce e non consiglio di usarlo se l'array è troppo grande, ma ha funzionato per me.

È necessario includere la libreria Json nel progetto. Se stai sviluppando su Android, è incluso:

/**
 * 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',
           ....
     },
      ...
 ]

Controlla il codice Easy per questo output

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

1

Puoi farlo facilmente in Kotlin usando il seguente codice:

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

Fondamentalmente, devi solo fornire un Arraydi YourClassoggetti.


Perché stai usando PrettyPrinting?
Antroid

@antroid mi sono dimenticato di rimuoverlo ^^
xarlymg89

0

puoi ottenere il valore List senza utilizzare l' oggetto Type .

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

L'ho testato e funziona.


0

a Kotlin :

val jsonArrayString = "['A','B','C']"

val gson = Gson()

val listType: Type = object : TypeToken<List<String?>?>() {}.getType()

val stringList : List<String> = gson.fromJson(
                            jsonArrayString,
                            listType)
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.