如何使用Gson创建多个对象以及如何使用一个JSON文件在Java类中显式引用不同的对象?

时间:2013-11-15 09:13:16

标签: java json gson

我有一个像这样的JSON文件:

{"id" : "1", "name" : "David"}  // this represent testdata for the class Person
{"accountid" : "1188", "accountnumber" : "119295567"}  // this represent testdata for the class account
{"id" : "22", "date" : "22.11.2013"} // this represent testdata for the class transaction

现在,我有三个Java类(具有合适的属性,如JSON文件和get-和set方法)

  • 帐户
  • 交易

我已经编写了一个Junit Test并将使用JSON文件。我将仅使用一个JSON文件生成三个不同的对象。

我怎么能用Gson做到这一点?这是我到目前为止尝试反序列化Person对象。

Gson gson = new GsonBuilder().create();
String jsonTestFile = FileUtils.readFileToString(new File(this.pathForJsonTestFile
         + "testFile.json"));

Person person = gson.fromJson(jsonTestFile,
         Person.class);

但是如何根据JSON显式创建帐户对象或事务对象或person对象?

1 个答案:

答案 0 :(得分:2)

如果你的JSON中有一个字段告诉你你正在尝试解析什么类型的对象,那么它将“更容易”,因为在你的数据中你可以区分对象的字段结构,你可以解析你的JSON根据它。我的意思是,如果你有accountid字段,它是一个帐户类,依此类推。

因此,您需要做的是查看您的JSON并确定要用于反序列化的类。要做类似的事情,你可以使用JsonParser类来返回一个可浏览的对象树,然后激活一个标准的Gson反序列化。

我准备了一个代码,您可以在IDE中复制和运行以显示如何执行此操作。

package stackoverflow.questions.q19997365;

import com.google.gson.*;

public class Q19997365 {

   public static class Person {
      String id;
      String name;

      @Override
      public String toString() {
         return "Person [id=" + id + ", name=" + name + "]";
      }
   }

   public static class Account {
      String accountid;
      String accountnumber;

      @Override
      public String toString() {
         return "Account [accountid=" + accountid + ", accountNumber=" + accountnumber + "]";
      }

   }

   public static class Transaction {
      String id;
      String date;

      @Override
      public String toString() {
         return "Transaction [id=" + id + ", date=" + date + "]";
      }

   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      String json1 = "{\"id\" : \"1\", \"name\" : \"David\"}"; // this represent testdata for the class Person
      String json2 = "{\"accountid\" : \"1188\", \"accountnumber\" : \"119295567\"}"; // this represent testdata for the class account
      String json3 = "{\"id\" : \"22\", \"date\" : \"22.11.2013\"}"; // this represent testdata for the class transaction

      System.out.println(extractFromJson(json1));
      System.out.println(extractFromJson(json2));
      System.out.println(extractFromJson(json3));

   }

   private static Object extractFromJson(String json) {
      Gson g = new Gson();
      JsonObject e = new JsonParser().parse(json).getAsJsonObject();
      if (e.get("name") != null)
         return g.fromJson(json, Person.class);
      if (e.get("accountid") != null)
         return g.fromJson(json, Account.class);
      if (e.get("date") != null)
         return g.fromJson(json, Transaction.class);

      return null;
   }

}

这是我的执行:

Person [id=1, name=David]
Account [accountid=1188, accountnumber=119295567]
Transaction [id=22, date=22.11.2013]

关键部分是extractFromJson方法,它可以完成所有工作。它使用JsonParser来窥探JSON字符串,然后调用Gson实例来执行正确的反序列化。

三个最后的笔记

  1. 该方法每次实例化Gson,效率不高,但在这里我想向您展示这个概念,您可以轻松改进这一点。
  2. 您的date字段不是Gson默认情况下可以解析的日期,您需要更改日期格式,例如this
  3. extractFromJson方法类似于工厂模式,在这种模式中,您无法知道将返回什么类型的对象。因此Object是返回类型,您需要instanceof +强制转换才能正确管理它。