Analisando a matriz JSON em java.util.List com Gson

119

Eu tenho um JsonObjectnome "mapping"com o seguinte conteúdo:

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

Eu sei que posso obter o array "servers"com:

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

E agora eu quero analisar isso JsonArrayem um java.util.List...

Qual é a maneira mais fácil de fazer isso?

Abel Callejo
fonte
2
@ruakh, existem muitas diferenças entre esse e esta questão. Este lida com Gson.
Abel Callejo
@AbelMelquiadesCallejo dê uma olhada na resposta.Eu espero que isso resolva seu problema.
Prateek
@ruakh sim, concordo com você e conheço JsonArrayimplementos Iterable. É que também estou encontrando novas maneiras além de adicionar uma nova biblioteca.
Abel Callejo

Respostas:

272

Definitivamente, a maneira mais fácil de fazer isso é usando a função de análise padrão do Gson fromJson().

Há uma implementação dessa função adequada para quando você precisa desserializar em qualquer ParameterizedType(por exemplo, qualquer List), que é fromJson(JsonElement json, Type typeOfT).

No seu caso, você só precisa obter o Typede a List<String>e, em seguida, analisar a matriz JSON nisso Type, assim:

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

No seu caso yourJsoné a JsonElement, mas também pode ser a String, any Readerou a JsonReader.

Você pode querer dar uma olhada na documentação da API Gson .

MikO
fonte
7
Typepode ser encontrado em qual pacote?
Abel Callejo
10
Typeé uma interface integrada Java localizada no pacotejava.lang.reflect
MikO
Tive que usar em getString()vez de get()ou então .fromJson()estava reclamando.
lenooh
@MikO Eu tenho uma pergunta semelhante com Gson aqui . Eu queria ver se você pode me ajudar. Eu tenho uma solução, mas o problema é que parece muito complicado apenas analisar um JSON em um mapa.
john
18

O código abaixo está usando com.google.gson.JsonArray. Eu imprimi o número do elemento na lista, bem como os elementos na 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();
        }
    }

}

RESULTADO

List size is : 4

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

Eu li a solução do site oficial da Gson aqui

E este código para você:

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

Resultado mostrado no monitor:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1
Hoang
fonte
mesma resposta que a anterior - ainda usando o método estáticonew Gson().fromJson()
Abel Callejo
bem meu problema era outro mas seu trecho resolve meu problema. Eu armazenei a lista de cordas, mas quero buscar as cordas. Então seu snippet me lembra da classe I can put String []. Para buscar dados. Obrigado
badarshahzad
2

Consegui fazer o mapeamento de lista funcionar usando apenas @SerializedNamepara todos os campos ... nenhuma lógica ao redor Typefoi necessária.

Executando o código - na etapa 4 abaixo - por meio do depurador, posso observar que oList<ContentImage> mGalleryImages objeto foi preenchido com os dados JSON

Aqui está um exemplo:

1. O 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. Classe Java com a lista

public class FocusArea {

    @SerializedName("name")
    private String mName;

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

3. Classe Java para os itens da lista

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. O código Java que processa o JSON

    for (String key : focusAreaKeys) {

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

mapping.get("servers").getAsJsonArray()Desde que você comece com , se você tiver acesso ao Guava Streams , você pode fazer o seguinte:

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

O Note StreamSupportnão será capaz de trabalhar no JsonElementtipo, por isso é insuficiente.

Alex Moore-Niemi
fonte