【问题标题】:Parse JSON file using GSON使用 GSON 解析 JSON 文件
【发布时间】:2013-04-28 23:15:53
【问题描述】:

我想在 JAVA 中使用 GSON 解析这个 JSON 文件:

{
    "descriptor" : {
        "app1" : {
            "name" : "mehdi",
            "age" : 21,
            "messages": ["msg 1","msg 2","msg 3"]
        },
        "app2" : {
            "name" : "mkyong",
            "age" : 29,
            "messages": ["msg 11","msg 22","msg 33"]
        },
        "app3" : {
            "name" : "amine",
            "age" : 23,
            "messages": ["msg 111","msg 222","msg 333"]
        }
    }
}

但我不知道如何访问根元素:descriptor,之后是 app3 元素,最后是 name 元素。

我遵循了本教程http://www.mkyong.com/java/gson-streaming-to-read-and-write-json/,但它没有显示具有根元素和子元素的情况。

【问题讨论】:

标签: java json parsing gson


【解决方案1】:

Imo,使用 GSON 解析 JSON 响应的最佳方法是创建与您的响应“匹配”的类,然后使用 Gson.fromJson() 方法。
例如:

class Response {
    Map<String, App> descriptor;
    // standard getters & setters...
}

class App {
  String name;
  int age;
  String[] messages;
  // standard getters & setters...
}

然后只需使用:

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

其中yourJson 可以是String、任何ReaderJsonReaderJsonElement

最后,如果你想访问任何特定的字段,你只需要这样做:

String name = response.getDescriptor().get("app3").getName();

您始终可以按照其他答案中的建议手动解析 JSON,但我个人认为这种方法更清晰,更易于长期维护,并且更适合 JSON 的整体理念。

【讨论】:

  • 我相信这比“手动解析器”方法更能体现 JSON 的精神
  • 谢谢,但是 JSON 文件不会只包含 app1、app2、app3,它将是动态的,所以我将无法修复类属性..
  • @Mehdi 查看编辑后的代码,它更简单,允许您在 JSON 响应中包含任意数量的 app 对象,只需将提示更改为 Map ...顺便说一句,如果您有任意数量的应用程序对象,您应该在原始帖子中说出来! ;)
  • @MikO:谢谢,我按照你说的做了,我改变了整个项目并创建了类,但是我得到了一个 nullPointerException,你能检查我的新问题吗:stackoverflow.com/questions/16416965/…谢谢你:)
  • @B.ClayShannon,只是标准的 getter 和 setter!例如:public String getName() { return this.name; }public void setName(String name) { this.name = name; }
【解决方案2】:

我使用的是 gson 2.2.3

public class Main {

/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {

    JsonReader jsonReader = new JsonReader(new FileReader("jsonFile.json"));

    jsonReader.beginObject();

    while (jsonReader.hasNext()) {

    String name = jsonReader.nextName();
        if (name.equals("descriptor")) {
             readApp(jsonReader);

        }
    }

   jsonReader.endObject();
   jsonReader.close();

}

public static void readApp(JsonReader jsonReader) throws IOException{
    jsonReader.beginObject();
     while (jsonReader.hasNext()) {
         String name = jsonReader.nextName();
         System.out.println(name);
         if (name.contains("app")){
             jsonReader.beginObject();
             while (jsonReader.hasNext()) {
                 String n = jsonReader.nextName();
                 if (n.equals("name")){
                     System.out.println(jsonReader.nextString());
                 }
                 if (n.equals("age")){
                     System.out.println(jsonReader.nextInt());
                 }
                 if (n.equals("messages")){
                     jsonReader.beginArray();
                     while  (jsonReader.hasNext()) {
                          System.out.println(jsonReader.nextString());
                     }
                     jsonReader.endArray();
                 }
             }
             jsonReader.endObject();
         }

     }
     jsonReader.endObject();
}
}

【讨论】:

  • 谢谢 :) 但是为什么我们必须在每个方法中设置 jsonReader.beginObject();jsonReader.endObject(); 呢? (main 和 readApp)谢谢 :)
  • 我同意巫女的观点。 GSON 是一个非常强大的库,用于转换 JSON-Java 对象,反之亦然。我在大多数项目中都使用过它。
【解决方案3】:

在解决此类问题时要记住的一点是,在 JSON 文件中,{ 表示 JSONObject[ 表示 JSONArray。如果能够妥善管理它们,就很容易完成解析 JSON 文件的任务。上面的代码对我真的很有帮助,我希望这个内容能给上面的代码增加一些意义。

Gson JsonReader documentation 解释了如何处理 JsonObjectsJsonArrays 的解析:

  • 在数组处理方法中,首先调用 beginArray() 来使用数组的左括号。然后创建一个累加值的 while 循环,当 hasNext() 为 false 时终止。最后,通过调用 endArray() 读取数组的右括号。
  • 在对象处理方法中,首先调用 beginObject() 以使用对象的左大括号。然后创建一个 while 循环,根据局部变量的名称为其赋值。当 hasNext() 为假时,该循环应该终止。最后,通过调用 endObject() 读取对象的右大括号。

【讨论】:

    猜你喜欢
    • 2012-04-21
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    相关资源
    最近更新 更多