2

我有一个这样的 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 测试并将使用 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 显式创建帐户对象或事务对象或人员对象?

4

1 回答 1

2

如果您的 JSON 中有一个字段告诉您要解析的对象类型,它会“更容易”,但是,由于在您的数据中您可以按字段结构区分对象,您可以根据它解析您的 JSON . 我的意思是,如果你有accountid字段,它就是一个 Account 类,等等。

因此,您要做的就是查看您的 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 方法。它使用 aJsonParser窥探 JSON 字符串,然后调用 Gson 实例进行正确的反序列化。

三个最后的笔记

  1. 该方法每次都实例化 Gson,效率不高,但在这里我想向您展示这个概念,您可以轻松改进这一点。
  2. 您的date字段不是 Gson 默认可以解析的日期,您需要更改日期格式,例如看这个
  3. extractFromJson方法有点像工厂模式,在这种模式下你不知道会返回什么样的对象。Object返回类型也是如此,您需要一个instanceof+ 强制转换来正确管理它。
于 2013-11-15T22:58:14.410 回答