Analizando la matriz JSON en java.util.List con Gson

119

Tengo un JsonObjectnombre "mapping"con el siguiente contenido:

{
    "client": "127.0.0.1",
    "servers": [
        "8.8.8.8",
        "8.8.4.4",
        "156.154.70.1",
        "156.154.71.1"
    ]
}

Sé que puedo obtener la matriz "servers"con:

mapping.get("servers").getAsJsonArray()

Y ahora quiero analizar eso JsonArrayen unjava.util.List ...

¿Cuál es la forma más sencilla de hacer esto?

Abel Callejo
fuente
2
@ruakh hay muchas diferencias entre esa y esta pregunta. Éste se ocupa de Gson.
Abel Callejo
@AbelMelquiadesCallejo echa un vistazo a la respuesta, espero que resuelva tu problema.
Prateek
@ruakh si estoy de acuerdo contigo y conozco JsonArrayimplementos Iterable. Es solo que también estoy encontrando nuevas formas además de agregar una nueva biblioteca.
Abel Callejo

Respuestas:

273

Definitivamente, la forma más fácil de hacerlo es utilizando la función de análisis predeterminada de Gson fromJson() .

Existe una implementación de esta función adecuada para cuando necesita deserializar en cualquier ParameterizedType(por ejemplo, cualquiera List), que es fromJson(JsonElement json, Type typeOfT).

En su caso, solo necesita obtener el valor Typede a List<String>y luego analizar la matriz JSON en eso Type, así:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

En su caso yourJsones a JsonElement, pero también podría ser a String, any Readero aJsonReader .

Es posible que desee echar un vistazo a la documentación de la API de Gson .

MikO
fuente
7
Typese puede encontrar en qué paquete?
Abel Callejo
10
Typees una interfaz incorporada de Java ubicada en el paquetejava.lang.reflect
MikO
Tuve que usar en getString()lugar de get()o de lo contrario me .fromJson()estaba quejando.
lenooh
@MikO Tengo una pregunta similar con Gson aquí . Quería ver si puedes ayudarme. Tengo una solución, pero el problema es que parece muy complicado analizar un JSON en un mapa.
Juan
18

El siguiente código está usando com.google.gson.JsonArray. Imprimí el número de elementos en la lista, así como los elementos en la lista

import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


public class Test {

    static String str = "{ "+ 
            "\"client\":\"127.0.0.1\"," + 
            "\"servers\":[" + 
            "    \"8.8.8.8\"," + 
            "    \"8.8.4.4\"," + 
            "    \"156.154.70.1\"," + 
            "    \"156.154.71.1\" " + 
            "    ]" + 
            "}";

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            JsonParser jsonParser = new JsonParser();
            JsonObject jo = (JsonObject)jsonParser.parse(str);
            JsonArray jsonArr = jo.getAsJsonArray("servers");
            //jsonArr.
            Gson googleJson = new Gson();
            ArrayList jsonObjList = googleJson.fromJson(jsonArr, ArrayList.class);
            System.out.println("List size is : "+jsonObjList.size());
                    System.out.println("List Elements are  : "+jsonObjList.toString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

SALIDA

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]
Prateek
fuente
8

Leí la solución del sitio web oficial de Gson aquí

Y este código para ti:

    String json = "{"client":"127.0.0.1","servers":["8.8.8.8","8.8.4.4","156.154.70.1","156.154.71.1"]}";

    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
    JsonArray jsonArray = jsonObject.getAsJsonArray("servers");

    String[] arrName = new Gson().fromJson(jsonArray, String[].class);

    List<String> lstName = new ArrayList<>();
    lstName = Arrays.asList(arrName);

    for (String str : lstName) {
        System.out.println(str);
    }    

Mostrar resultado en el monitor:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1
Hoang
fuente
la misma respuesta que la anterior, aún usando el método estáticonew Gson().fromJson()
Abel Callejo
Bueno, mi problema era otro, pero tu fragmento resuelve mi problema. Guardé la lista de cadenas pero quiero ir a buscarlas. Luego, su fragmento me recuerda de su clase Puedo poner String []. Para obtener datos. Gracias
badarshahzad
2

Pude hacer que el mapeo de la lista funcionara con solo usar @SerializedNamepara todos los campos ... no Typeera necesaria ninguna lógica .

Al ejecutar el código, en el paso n. ° 4 a continuación , a través del depurador, puedo observar que el List<ContentImage> mGalleryImagesobjeto se completó con los datos JSON

He aquí un ejemplo:

1. El JSON

   {
    "name": "Some House",
    "gallery": [
      {
        "description": "Nice 300sqft. den.jpg",
        "photo_url": "image/den.jpg"
      },
      {
        "description": "Floor Plan",
        "photo_url": "image/floor_plan.jpg"
      }
    ]
  }

2. Clase Java con la Lista

public class FocusArea {

    @SerializedName("name")
    private String mName;

    @SerializedName("gallery")
    private List<ContentImage> mGalleryImages;
}

3. Clase Java para los elementos de la lista

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. El código Java que procesa JSON

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }
Gene Bo
fuente
0

Dado que comienza con mapping.get("servers").getAsJsonArray(), si tiene acceso a Guava Streams , puede hacer lo siguiente:

List<String> servers = Streams.stream(jsonArray.iterator())
                              .map(je -> je.getAsString())
                              .collect(Collectors.toList());

Note StreamSupportno podrá trabajar en el JsonElementtipo, por lo que es insuficiente.

Alex Moore-Niemi
fuente