【问题标题】:JSON parsing using Gson for Java使用 Gson for Java 解析 JSON
【发布时间】:2011-07-26 08:03:52
【问题描述】:

我想解析来自 String 类型的 JSON 数据。 我正在使用Google Gson

我有:

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

我的班级是:

public class JsonParsing{

   public void parse(String jsonLine) {

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

   }

}

【问题讨论】:

标签: java json gson


【解决方案1】:

这是执行此操作的简单代码,我避免了所有检查,但这是主要思想。

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

为了使使用更通用 - 您会发现 Gson's javadocs 非常清晰且很有帮助。

【讨论】:

  • JsonObject 扩展了 JsonElement,所以两者都是。
  • 第一行抛出cannot instance of the type of JsonParser on version gson-2.2.4.jar
  • 字符串结果 = jobject.get("translatedText").toString();此结果将包括双引号。字符串结果 = jobject.get("translatedText").getAsString();不包括引号。
  • 我是唯一一个认为 Gson 98% 的时间都把事情复杂化的人吗?一个简单的 JSONObject 就可以了,但我们都那么讨厌 try/catch 吗?
  • 我需要使用解析器类,但是,我得到了 MalformedJsonException,所以我必须能够使用 JsonParser 执行 SetLeinient。怎么样?
【解决方案2】:

使用 Gson 求解
我会为 json 字符串中的单个参数创建一个类。或者,您可以创建一个名为“Data”的主类,然后类似地创建内部类。为了清楚起见,我创建了单独的类。

类如下。

  • 数据
  • 翻译
  • 翻译文本

在 JsonParsing 类中,我们调用方法“parse”gson.fromJson(jsonLine, Data.class),它将使用反射将字符串转换为 java 对象。

一旦我们可以访问“数据”对象,我们就可以单独访问每个参数。

因为我不在我的开发机器上,所以没有机会测试这段代码。但这应该会有所帮助。

一些很好的例子和文章。
http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html
http://sites.google.com/site/gson/gson-user-guide

代码

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

【讨论】:

  • 你不需要在这些助手类上设置一些设置器吗?没有任何东西可以设置private String translatedText而不违反访问控制,所以fromJSON无法在没有选择反射践踏访问控制的JVM中设置它。
  • @Mike Samuel shoot 完全忘记了二传手
【解决方案3】:

最简单的事情通常是创建匹配的对象层次结构,如下所示:

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

然后使用 GSON 绑定,通过字段遍历对象层次结构。添加 getter 和 setter 对基本数据容器毫无意义。

比如:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;

【讨论】:

  • 那么你的对象结构与 JSON 不匹配。
【解决方案4】:

您可以为 json 对象创建相应的 java 类。整数、字符串值可以按原样映射。 Json 可以这样解析-

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

这是一个例子-http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html

【讨论】:

    【解决方案5】:

    在我的第一个 gson 应用程序中,我避免使用额外的类来捕获值 主要是因为我使用 json 来处理配置问题

    尽管缺乏信息(甚至是 gson 页面),但这就是我找到并使用的:

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

    gson 每次看到一个 {},它都会创建一个 Map(实际上是一个 gson StringMap)

    gson 每次看到一个'',它都会创建一个字符串

    gson 每次看到一个数字,它都会创建一个 Double

    gson 每次看到一个 [],它都会创建一个 ArrayList

    您可以利用这些事实(结合)来发挥自己的优势

    这就是制作这个东西的代码

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

    【讨论】:

    • 我觉得这太棒了。
    【解决方案6】:
        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")
        }
    

    像这样解析 JSON 的简单示例

    { "some_array" : "[\"some_element\":1,\"some_more_element\":2]" , “一些其他元素”:3 }

    【讨论】:

      【解决方案7】:

      您可以使用单独的类来表示 JSON 对象,并使用 @SerializedName 注释来指定要为每个数据成员抓取的字段名称:

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

      然后您可以使用Gson 对象在您的 parse() 方法中进行解析:

      Gson gson = new Gson();
      Response response = gson.fromJson(jsonLine, Response.class);
      
      System.out.println("Translated text: " + response.getTranslatedText());
      

      使用这种方法,您可以重用 Response 类来添加任何其他附加字段,以获取您可能希望从 JSON 中提取的其他数据成员——以防您想要进行更改以获取结果,例如,一次调用中的多个翻译,或获取检测到的源语言的附加字符串。

      【讨论】:

        【解决方案8】:

        您可以使用 JsonPath 查询来提取值。有了Gson支持的JsonSurfer,你的问题只需要两行代码就可以解决!

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

        【讨论】:

          【解决方案9】:

          首先使用下面的解析站点生成getter和setter

          http://www.jsonschema2pojo.org/

          现在使用 Gson

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

          现在使用对象来获取数据、翻译文本等值

          【讨论】:

            【解决方案10】:

            一行代码:

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

            【讨论】:

              【解决方案11】:

              一种方法是创建一个 JsonObject 并遍历参数。例如

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

              然后你可以提取像这样的bean值:

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

              希望这会有所帮助。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-04-26
                • 2013-05-01
                • 1970-01-01
                • 2011-02-12
                相关资源
                最近更新 更多