173

I would like to parse data from JSON which is of type String. I am using Google Gson.

I have:

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

and my class is:

public class JsonParsing{

   public void parse(String jsonLine) {

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

   }

}
abhi
  • 1,760
  • 1
  • 24
  • 40
Martynas
  • 2,545
  • 7
  • 30
  • 36
  • Similar: https://stackoverflow.com/questions/4110664/gson-directly-convert-string-to-jsonobject-no-pojo – Vadzim Dec 19 '17 at 16:00

11 Answers11

263

This is simple code to do it, I avoided all checks but this is the main idea.

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

To make the use more generic - you will find that Gson's javadocs are pretty clear and helpful.

Vadzim
  • 24,954
  • 11
  • 143
  • 151
MByD
  • 135,866
  • 28
  • 264
  • 277
  • 1
    JsonObject extends JsonElement, so it is both. – MByD Mar 30 '11 at 19:45
  • the first line throws cannot instantiate of the type JsonParser on version gson-2.2.4.jar – Illegal Argument Jun 13 '14 at 11:28
  • 3
    String result = jobject.get("translatedText").toString(); This results will include the double quotes. String result = jobject.get("translatedText").getAsString(); doesn't include the quotes. – user1165560 Oct 23 '15 at 23:02
  • Al I the only one who thinks Gson overcomplicates things 98% of the time? A simple JSONObject would do, but we all hate try/catch that much? – tricknology Jan 18 '17 at 08:39
  • I need to use the parser class, however, I am getting the MalformedJsonException, so I have to be able to do SetLeinient with JsonParser. How? – Mason Wang Jun 12 '17 at 15:55
  • @IllegalArgument It deprecated. No need to instantiate this class, use the static methods instead as `JsonParser.parse(jsonString);` – Minkyu Kim Oct 26 '21 at 02:38
122

In my first gson application I avoided using additional classes to catch values mainly because I use json for config matters

despite the lack of information (even gson page), that's what I found and used:

starting from

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

Each time gson sees a {}, it creates a Map (actually a gson StringMap )

Each time gson sees a '', it creates a String

Each time gson sees a number, it creates a Double

Each time gson sees a [], it creates an ArrayList

You can use this facts (combined) to your advantage

Finally this is the code that makes the thing

        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
  • 1,619
  • 1
  • 13
  • 14
21

Simplest thing usually is to create matching Object hierarchy, like so:

public class Wrapper {
   public Data data;

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

and then bind using GSON, traverse object hierarchy via fields. Adding getters and setters is pointless for basic data containers.

So something like:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;
StaxMan
  • 113,358
  • 34
  • 211
  • 239
15

You can create corresponding java classes for the json objects. The integer, string values can be mapped as is. Json can be parsed like this-

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

Here is an example- http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html

blue01
  • 2,035
  • 2
  • 23
  • 38
10

You can use a separate class to represent the JSON object and use @SerializedName annotations to specify the field name to grab for each data member:

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

Then you can do the parsing in your parse() method using a Gson object:

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

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

With this approach, you can reuse the Response class to add any other additional fields to pick up other data members you might want to extract from JSON -- in case you want to make changes to get results for, say, multiple translations in one call, or to get an additional string for the detected source language.

rmtheis
  • 5,992
  • 12
  • 61
  • 78
9

One way would be created a JsonObject and iterating through the parameters. For example

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

Then you can extract bean values like:

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

Hope this helps.

Anand Tuli
  • 179
  • 2
  • 3
5
    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")
    }

A simple example to parse a JSON like this

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

5

Using Gson to Solve
I would create a class for individual parameter in the json String. Alternatively you can create one main class called "Data" and then create inner classes similarly. I created separate classes for clarity.

The classes are as follows.

  • Data
  • Translations
  • TranslatedText

In the class JsonParsing the method "parse" we call gson.fromJson(jsonLine, Data.class) which will convert the String in java objects using Reflection.

Once we have access to the "Data" object we can access each parameter individually.

Didn't get a chance to test this code as I am away from my dev machine. But this should help.

Some good examples and articles.
http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html
http://sites.google.com/site/gson/gson-user-guide

Code

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
  • 5,439
  • 5
  • 28
  • 36
  • Don't you need some setters on those helper classes? Nothing can set the `private String translatedText` without violating access control, so there's no way `fromJSON` could set it in JVMs that have not opted-into reflection trampling all over access control. – Mike Samuel Mar 30 '11 at 19:47
  • @Mike Samuel shoot completely forgot about the Setters – kensen john Mar 30 '11 at 20:14
4

Firstly generate getter and setter using below parsing site

http://www.jsonschema2pojo.org/

Now use Gson

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

Now use object to get values such as data,translationText

ElOjcar
  • 301
  • 2
  • 4
  • 12
Nilesh
  • 1,013
  • 14
  • 21
2

You can use a JsonPath query to extract the value. And with JsonSurfer which is backed by Gson, your problem can be solved by simply two line of code!

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

One line code:

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