Java GSON解析 - 数组和嵌套类

时间:2013-12-11 22:07:31

标签: java json gson

我正在为求职者详细信息调用第三方REST服务,并以JSON格式发回响应。 JSON数据看起来像

[
  {
   "Id": 1
  "County": "sample string 16",
  "Country": "sample string 17",
  "AtAddressSinceMonth": 1,
  "AtAddressSinceYear": 1,
  "AtAddressUntilMonth": 1,
  "AtAddressUntilYear": 1,
   "DateOfBirth": "2013-12-11T14:25:27.3753327-05:00",
   "Documents": [
      {
        "Type": "sample string 1",
        "Description": "sample string 2",
        "File": "sample string 3"
       },
      {
        "Type": "sample string 1",
        "Description": "sample string 2",
        "File": "sample string 3"
      },

    ],
    "Events": [
      {
        "StartDateTime": "2013-12-11T14:25:27.3753327-05:00",
        "EndDateTime": "2013-12-11T14:25:27.3753327-05:00",
        "Description": "sample string 3",
        "Attendees": [
          {
            "EmailAddress": "sample string 1",
            "FirstName": "sample string 2",
            "LastName": "sample string 3"
          },
          {
            "EmailAddress": "sample string 1",
            "FirstName": "sample string 2",
            "LastName": "sample string 3"
          }
        ]
       },
      {
        "StartDateTime": "2013-12-11T14:25:27.3753327-05:00",
        "EndDateTime": "2013-12-11T14:25:27.3753327-05:00",
        "Description": "sample string 3",
        "Attendees": [
          {
            "EmailAddress": "sample string 1",
            "FirstName": "sample string 2",
            "LastName": "sample string 3"
          },
      ....
      ....
  {
    "Id": 1,
   "County": "sample string 16",
    "Country": "sample string 17",
    "AtAddressSinceMonth": 1,
    "AtAddressSinceYear": 1,
   "AtAddressUntilMonth": 1,
   "AtAddressUntilYear": 1,
...
...

      }
     ]
   }
  ]

它继续这样......我已经为所有嵌套变量和相应的set和get方法定义了一个静态类JobSeeker,其中包含所有变量和静态内部类。

另外,使用变量protected List jobSeeker创建另一个类ArrayOfJobSeeker;我的类定义看起来像

public class ArrayOfJobSeeker {

protected List<ArrayOfJobSeeker.JobSeeker> jobSeeker;

public List<ArrayOfJobSeeker.JobSeeker> getJobSeeker() {
    if (jobSeeker == null) {
        jobSeeker = new ArrayList<ArrayOfJobSeeker.JobSeeker>();
    }
    return this.jobSeeker;
}



public static class JobSeeker {


    protected String address;

    protected String atAddressSinceMonth;

    protected String atAddressSinceYear;
    protected String atAddressUntilMonth;
    protected String atAddressUntilYear;
    protected String city;
    protected String country;
    protected String county;
    protected XMLGregorianCalendar dateOfBirth;
    protected ArrayOfJobSeeker.JobSeeker.Documents documents;
    protected String emailAddress;
    protected ArrayOfJobSeeker.JobSeeker.Events events;
    protected String extension;
    protected String firstName;
    protected String genderCode;
    protected ArrayOfJobSeeker.JobSeeker.HistoryActivities historyActivities;
    protected String id;
    protected String lastName;
    protected String maidenName;
    protected String middleName;

和嵌套的内部类

    public static class Documents {


        protected List<ArrayOfJobSeeker.JobSeeker.Documents.Document> document;
        public List<ArrayOfJobSeeker.JobSeeker.Documents.Document> getDocument() {
            if (document == null) {
                document = new ArrayList<ArrayOfJobSeeker.JobSeeker.Documents.Document>();
            }
            return this.document;
        }              

          public static class Document {

            protected String description;
            protected String file;
            protected String type;
       }  //end Document
   } // end Documents

} //结束求职者

我不太确定如何使用GSON解析这个嵌套数组,因为此代码会抛出错误

File file = new File("c:/temp/testJSON.txt"); 
BufferedReader br = new BufferedReader(new FileReader(file));
Gson gson = new Gson();   
gson.fromJson(br, ArrayOfJobSeeker.class) 

请帮忙。

由于

2 个答案:

答案 0 :(得分:1)

盲目地将任意json反序列化为强类型类结构的问题是它太脆弱了;一个错位的类型和KABOOM!

这就是我要做的。你正在使用Java,所以抛出一些groovy:

import groovy.json.JsonSlurper;
...
JsonSlurper jsonParser = new JsonSlurper();
List<Map> jsonMap = (List<Map>)jsonParser.parse(new FileReader( jsonFile));

JsonSlurper将json解析为分层HashMaps列表,每个HashMaps包含必要的数组和原始包装器(Long,Boolean等);你不提前创建自定义类,只需解析原始json;完成。

您可以按原样使用jsonMap'(这就是我要做的)。或者,如果您坚持创建自己的类来存储所有数据以及getter和setter,请浏览jsonMap使用您的调试器,遍历对象以查看类型,然后您将确切知道您要实现的任何类所需的类型。与Json相比,JsonSlurper的唯一缺点是,它不会反序列化为像Gson这样的自定义类;你需要自己做那部分。

PS:如果您的json以[]开头/结尾,jsonParser会返回List<Map>,如果它以{}开头/结尾,则返回HashMap<String,Object>为封闭的对象。

答案 1 :(得分:1)

在问题中引用您的评论,您的代码是否真的打印出整个json字符串?我想你只会得到第一个元素 如果可能的话,我建议你拿出内部类,并做一些像

这样的事情
JsonArray jarray = new JsonParser().parse(json).getAsJsonArray();
for (JsonElement e : jarray) {
    JsonObject jobSeeker = e.getAsJsonObject();

    JsonArray events = e.get("Events").getAsJsonArray();
    JsonArray documents = e.get("Documents").getAsJsonArray();
    // iterate the array, deserialize the objects and do your work

    jobSeeker.remove("Events");
    jobSeeker.remove("Documents");
    // deal with the job seeker;
}

这似乎不是一个好方法,但我认为它应该有用。