Usando GSON para analisar uma matriz JSON

110

Tenho um arquivo JSON como este:

[
    {
        "number": "3",
        "title": "hello_world",
    }, {
        "number": "2",
        "title": "hello_world",
    }
]

Antes, quando os arquivos tinham um elemento raiz, eu usava:

Wrapper w = gson.fromJson(JSONSTRING, Wrapper.class);

código, mas não consigo pensar em como codificar a Wrapperclasse, pois o elemento raiz é uma matriz.

Eu tentei usar:

Wrapper[] wrapper = gson.fromJson(jsonLine, Wrapper[].class);

com:

public class Wrapper{

    String number;
    String title;

}

Mas não tive sorte. De que outra forma posso ler isso usando este método?

PS Eu tenho isso para funcionar usando:

JsonArray entries = (JsonArray) new JsonParser().parse(jsonLine);
String title = ((JsonObject)entries.get(0)).get("title");

Mas eu preferiria saber como fazer (se possível) com os dois métodos.

Eduardo
fonte
4
Tem certeza de que há vírgulas após os elementos do título? Se você removê-los, Wrapper[] data = gson.fromJson(jElement, Wrapper[].class);funcionará bem para mim.
Pshemo
1
Esse será o problema .. um erro tão simples!
Eduardo

Respostas:

112

O problema é causado por uma vírgula no final de (no seu caso, cada ) objeto JSON colocado na matriz:

{
    "number": "...",
    "title": ".." ,  //<- see that comma?
}

Se você removê-los, seus dados se tornarão

[
    {
        "number": "3",
        "title": "hello_world"
    }, {
        "number": "2",
        "title": "hello_world"
    }
]

e

Wrapper[] data = gson.fromJson(jElement, Wrapper[].class);

deve funcionar bem.

Pshemo
fonte
1
@Snake BTW, no caso de jacksonbiblioteca e este comentário, criar array e envolvê-lo Arrays.asList(..)é mais rápido do que criar uma lista usando TypeRefence. Não testei com a gsonbiblioteca, mas pode valer a pena fazer um benchmark.
Pshemo,
39
Gson gson = new Gson();
Wrapper[] arr = gson.fromJson(str, Wrapper[].class);

class Wrapper{
    int number;
    String title;       
}

Parece funcionar bem. Mas há uma ,vírgula extra em sua string.

[
    { 
        "number" : "3",
        "title" : "hello_world"
    },
    { 
        "number" : "2",
        "title" : "hello_world"
    }
]
Narendra Pathai
fonte
16
public static <T> List<T> toList(String json, Class<T> clazz) {
    if (null == json) {
        return null;
    }
    Gson gson = new Gson();
    return gson.fromJson(json, new TypeToken<T>(){}.getType());
}

chamada de amostra:

List<Specifications> objects = GsonUtils.toList(products, Specifications.class);
chenyueling
fonte
4
Para mim, isso é transformar meus objetos em uma Lista de objetos LinkedTreeMap em vez de uma Lista de objetos de especificação (por exemplo).
Ryan Newsom
Onde você conseguiu a aula do GsonUtils?
rosu alin de
GsonUtilsé a aula onde ele colocou seu próprio toList()método.
user1438038
Isso não pode funcionar: o TypeToken deve criar um valor errado, pois T não é conhecido quando isso é compilado. Isso provavelmente criará o token de tipo para List <Object>. Você teria que usar a classe real ao criar o tipo.
Hans-Peter Störr
1
Wrapper[] data = gson.fromJson(jElement, Wrapper[].class);
Shahzeb Khan
fonte