Análise JSON usando o Gson para Java

154

Eu gostaria de analisar dados do JSON, que é do tipo String . Estou usando o Google Gson .

Eu tenho:

jsonLine = "
{
 "data": {
  "translations": [
   {
    "translatedText": "Hello world"
   }
  ]
 }
}
";

e minha turma é:

public class JsonParsing{

   public void parse(String jsonLine) {

      // there I would like to get String "Hello world"

   }

}
Martynas
fonte

Respostas:

241

Este é um código simples, evitei todas as verificações, mas essa é a ideia principal.

 public String parse(String jsonLine) {
    JsonElement jelement = new JsonParser().parse(jsonLine);
    JsonObject  jobject = jelement.getAsJsonObject();
    jobject = jobject.getAsJsonObject("data");
    JsonArray jarray = jobject.getAsJsonArray("translations");
    jobject = jarray.get(0).getAsJsonObject();
    String result = jobject.get("translatedText").getAsString();
    return result;
}

Para tornar o uso mais genérico - você encontrará que os javadocs do Gson são bem claros e úteis.

MByD
fonte
1
JsonObject estende JsonElement, portanto são os dois.
MByD 30/03/11
a primeira linha joga não pode instanciar do tipo JsonParser na versão Gson-2.2.4.jar
Argumento Ilegal
3
String result = jobject.get ("translatorText"). ToString (); Estes resultados incluirão aspas duplas. String result = jobject.get ("translatorText"). GetAsString (); não inclui as aspas.
user1165560
Eu sou o único que acha que Gson complica demais as coisas 98% das vezes? Um simples JSONObject serviria, mas todos odiamos tentar / capturar isso?
tricknology
Eu preciso usar a classe analisador, no entanto, estou recebendo a MalformedJsonException, portanto, tenho que poder fazer SetLeinient com o JsonParser. Quão?
Mason Wang
111

No meu primeiro aplicativo gson, evitei usar classes adicionais para capturar valores, principalmente porque uso o json para questões de configuração

apesar da falta de informação (mesmo na página gson), foi o que encontrei e usei:

Começando de

Map jsonJavaRootObject = new Gson().fromJson("{/*whatever your mega complex object*/}", Map.class)

Cada vez que o gson vê um {}, ele cria um mapa (na verdade, um gson StringMap)

Cada vez que o gson vê um '', ele cria uma String

Cada vez que o gson vê um número, ele cria um Double

Cada vez que o gson vê um [], ele cria um ArrayList

Você pode usar esses fatos (combinados) para sua vantagem

Finalmente, este é o código que faz a coisa

        Map<String, Object> javaRootMapObject = new Gson().fromJson(jsonLine, Map.class);

    System.out.println(
        (
            (Map)
            (
                (List)
                (
                    (Map)
                    (
                        javaRootMapObject.get("data")
                    )
                 ).get("translations")
            ).get(0)
        ).get("translatedText")
    );
Jorge Sanchez
fonte
20

A coisa mais simples geralmente é criar a hierarquia de objetos correspondente, da seguinte forma:

public class Wrapper {
   public Data data;
}
static class Data {
   public Translation[] translations;
}
static class Translation {
   public String translatedText;
}

e depois vincule usando o GSON, percorra a hierarquia de objetos por meio de campos. Adicionar getters e setters não faz sentido para contêineres de dados básicos.

Então, algo como:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;
StaxMan
fonte
2
Em seguida, sua estrutura de objeto NÃO corresponde ao JSON.
StaxMan
14

Você pode criar classes java correspondentes para os objetos json. O número inteiro, os valores da sequência podem ser mapeados como estão. Json pode ser analisado assim -

Gson gson = new GsonBuilder().create(); 
Response r = gson.fromJson(jsonString, Response.class);

Aqui está um exemplo: http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html

blue01
fonte
8

Você pode usar uma classe separada para representar o objeto JSON e usar @SerializedNameanotações para especificar o nome do campo a ser capturado para cada membro de dados:

public class Response {

   @SerializedName("data")
   private Data data;

   private static class Data {
      @SerializedName("translations")
      public Translation[] translations;
   }

   private static class Translation {
      @SerializedName("translatedText")
      public String translatedText;
   }

   public String getTranslatedText() {
      return data.translations[0].translatedText;
   }
}

Então você pode fazer a análise no seu método parse () usando um Gsonobjeto:

Gson gson = new Gson();
Response response = gson.fromJson(jsonLine, Response.class);

System.out.println("Translated text: " + response.getTranslatedText());

Com essa abordagem, é possível reutilizar a Responseclasse para adicionar outros campos adicionais para selecionar outros membros de dados que você deseja extrair do JSON - caso deseje fazer alterações para obter resultados para, por exemplo, várias traduções em uma chamada, ou para obter uma sequência adicional para o idioma de origem detectado.

rmtheis
fonte
7

Uma maneira seria criar um JsonObject e iterar através dos parâmetros. Por exemplo

JsonObject jobj = new Gson().fromJson(jsonString, JsonObject.class);

Então você pode extrair valores de bean como:

String fieldValue = jobj.get(fieldName).getAsString();
boolean fieldValue = jobj.get(fieldName).getAsBoolean();
int fieldValue = jobj.get(fieldName).getAsInt();

Espero que isto ajude.

Anand Tuli
fonte
5

Usando o Gson para resolver
eu criaria uma classe para parâmetro individual na string json. Como alternativa, você pode criar uma classe principal chamada "Dados" e, em seguida, criar classes internas da mesma forma. Criei classes separadas para maior clareza.

As aulas são as seguintes.

  • Dados
  • Traduções
  • TranslatedText

Na classe JsonParsing, o método "parse" chamamos gson.fromJson(jsonLine, Data.class) que converterá a String em objetos java usando Reflection.

Uma vez que tenhamos acesso ao objeto "Dados", podemos acessar cada parâmetro individualmente.

Não tive a chance de testar esse código, pois estou longe da minha máquina de desenvolvimento. Mas isso deve ajudar.

Alguns bons exemplos e artigos.
http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html
http://sites.google.com/site/gson/gson-user-guide

Código

public class JsonParsing{

       public void parse(String jsonLine) {

           Gson gson = new GsonBuilder().create();
           Data data = gson.fromJson(jsonLine, Data.class);

           Translations translations = data.getTranslation();
           TranslatedText[] arrayTranslatedText = translations.getArrayTranslatedText(); //this returns an array, based on json string

           for(TranslatedText translatedText:arrayTranslatedText )
           {
                  System.out.println(translatedText.getArrayTranslatedText());
           }
       }

    }


    public class Data{
           private  Translations translations;
          public Translations getTranslation()
          {
             return translations;
          }

          public void setTranslation(Translations translations)
           {
                  this.translations = translations;
           }
    }

    public class Translations
    {
        private  TranslatedText[] translatedText;
         public TranslatedText[] getArrayTranslatedText()
         {
             return translatedText;
         }

           public void setTranslatedText(TranslatedText[] translatedText)
           {
                  this.translatedText= translatedText;
           }
    }

    public class TranslatedText
    {
        private String translatedText;
        public String getTranslatedText()
        {
           return translatedText;
        }

        public void setTranslatedText(String translatedText)
        {
           this.translatedText = translatedText;
        }
    }
kensen john
fonte
Você não precisa de alguns levantadores nessas classes auxiliares? Nada pode definir o private String translatedTextsem violar o controle de acesso; portanto, não há como fromJSONdefini-lo nas JVMs que não optaram pela reflexão atropelando todo o controle de acesso.
Mike Samuel
@ Mike Samuel shoot esqueci completamente os Setters
kensen john
3
    JsonParser parser = new JsonParser();
    JsonObject jo = (JsonObject) parser.parse(data);
    JsonElement je = jo.get("some_array");

    //Parsing back the string as Array
    JsonArray ja = (JsonArray) parser.parse(o.get("some_array").getAsString());
    for (JsonElement jo : ja) {
    JsonObject j = (JsonObject) jo;
        // Your Code, Access json elements as j.get("some_element")
    }

Um exemplo simples para analisar um JSON como este

{"some_array": "[\" some_element \ ": 1, \" some_more_element \ ": 2]", "some_other_element": 3}

Rahul Malhotra
fonte
2

Em primeiro lugar, gerar Getter And Setter usando o site de análise abaixo

http://www.jsonschema2pojo.org/

Agora use o Gson

GettetSetterClass object=new Gson().fromjson(jsonLine,GettetSetterClass.class);

Agora use object para obter valores como data, translationText

Nilesh Panchal
fonte
2

Você pode usar uma consulta JsonPath para extrair o valor. E com o JsonSurfer, que é apoiado pelo Gson, seu problema pode ser resolvido com apenas duas linhas de código!

    JsonSurfer jsonSurfer = JsonSurfer.gson();
    String result = jsonSurfer.collectOne(jsonLine, String.class, "$.data.translations[0].translatedText");
Leo Wang
fonte
1

Código de uma linha:

System.out.println(new Gson().fromJson(jsonLine,JsonObject.class).getAsJsonObject().get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString());
retArdos
fonte