Análisis JSON usando Gson para Java

154

Me gustaría analizar datos de JSON que son de tipo String. Estoy usando Google Gson .

Yo tengo:

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

y mi clase es:

public class JsonParsing{

   public void parse(String jsonLine) {

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

   }

}
Martynas
fuente

Respuestas:

241

Este es un código simple para hacerlo, evité todas las comprobaciones pero esta es la idea 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 hacer que el uso sea más genérico, encontrará que los javadocs de Gson son bastante claros y útiles.

MByD
fuente
1
JsonObject extiende JsonElement, por lo que son ambos.
MByD
los lanzamientos de primera línea no pueden crear instancias del tipo JsonParser en la versión gson-2.2.4.jar
Argumento ilegal
3
Resultado de cadena = jobject.get ("translateText"). ToString (); Estos resultados incluirán las comillas dobles. Cadena resultado = jobject.get ("translateText"). GetAsString (); No incluye las comillas.
user1165560
¿Soy el único que piensa que Gson complica demasiado las cosas el 98% del tiempo? Un simple JSONObject funcionaría, pero todos odiamos probar / atrapar tanto.
Tricknology
Necesito usar la clase parser, sin embargo, obtengo la MalformedJsonException, así que tengo que poder hacer SetLeinient con JsonParser. ¿Cómo?
Mason Wang
111

En mi primera aplicación gson evité usar clases adicionales para capturar valores principalmente porque uso json para cuestiones de configuración

a pesar de la falta de información (incluso la página de gson), eso es lo que encontré y usé:

empezando desde

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

Cada vez que gson ve un {}, crea un mapa (en realidad un gson StringMap)

Cada vez que gson ve un '', crea una cadena

Cada vez que gson ve un número, crea un Doble

Cada vez que gson ve un [], crea una ArrayList

Puede usar estos hechos (combinados) para su ventaja

Finalmente este es el código que hace la cosa

        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
fuente
20

Lo más simple generalmente es crear una jerarquía de Objetos coincidente, así:

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

y luego enlazar usando GSON, atravesar la jerarquía de objetos a través de campos. Agregar captadores y establecedores no tiene sentido para los contenedores de datos básicos.

Entonces algo como:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;
StaxMan
fuente
2
Entonces su estructura de objeto NO coincide con JSON.
StaxMan
8

Puede usar una clase separada para representar el objeto JSON y usar @SerializedNameanotaciones para especificar el nombre del campo para capturar para cada miembro de datos:

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

Luego puede hacer el análisis en su método parse () usando un Gsonobjeto:

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

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

Con este enfoque, puede reutilizar la Responseclase para agregar cualquier otro campo adicional para recoger otros miembros de datos que desee extraer de JSON, en caso de que desee realizar cambios para obtener resultados para, por ejemplo, múltiples traducciones en una sola llamada, o para obtener una cadena adicional para el idioma de origen detectado.

rmtheis
fuente
7

Una forma sería crear un JsonObject e iterar a través de los parámetros. Por ejemplo

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

Luego puede extraer valores de frijol como:

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

Espero que esto ayude.

Anand Tuli
fuente
5

Usando Gson para resolver
crearía una clase para parámetro individual en la cadena json. Alternativamente, puede crear una clase principal llamada "Datos" y luego crear clases internas de manera similar. Creé clases separadas para mayor claridad.

Las clases son las siguientes.

  • Datos
  • Traducciones
  • Texto traducido

En la clase JsonParsing llamamos al método "parse", gson.fromJson(jsonLine, Data.class)que convertirá la Cadena en objetos java usando Reflection.

Una vez que tenemos acceso al objeto "Datos" podemos acceder a cada parámetro individualmente.

No tuve la oportunidad de probar este código ya que estoy lejos de mi máquina de desarrollo. Pero esto debería ayudar.

Algunos buenos ejemplos y artículos.
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
fuente
¿No necesitas algunos setters en esas clases de ayuda? Nada puede configurarlo private String translatedTextsin violar el control de acceso, por lo que no hay forma de fromJSONconfigurarlo en JVM que no hayan optado por la reflexión pisoteando todo el control de acceso.
Mike Samuel
@Mike Samuel disparó completamente olvidado de los 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")
    }

Un ejemplo simple para analizar un JSON como este

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

Rahul Malhotra
fuente
2

En primer lugar, genere Getter and Setter utilizando el siguiente sitio de análisis

http://www.jsonschema2pojo.org/

Ahora usa Gson

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

Ahora use objeto para obtener valores como datos, translationText

Nilesh Panchal
fuente
2

Puede usar una consulta JsonPath para extraer el valor. ¡Y con JsonSurfer, respaldado por Gson, su problema puede resolverse simplemente con dos líneas de código!

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

Código de una línea:

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