【问题标题】:Deserialization of sometimes string and sometimes object with Gson使用 Gson 反序列化有时是字符串,有时是对象
【发布时间】:2013-10-28 23:24:12
【问题描述】:

我需要将这种类型的 JSON 数据解析为 java 对象:

{"id": 1, "blob": "example text"} 
{"id": 2, "blob": {"to": 1234, "from": 4321, "name": "My_Name"}}

我正在使用 Gson,但不知道如何解决这个特殊问题,即“blob”有时是字符串,有时是对象。

【问题讨论】:

  • 耶!您现在可以更改/修复格式吗?
  • 不太确定你在问什么。你的意思是如果我可以手动更改 JSON 的布局?
  • 你需要 blob": "示例文本值吗?
  • 是的,我需要这样我才能同时遇到 blob 是字符串的情况和 blob 是对象的情况。
  • @user1090614 如果“需要”真的是“想要”——即不需要一个愚蠢的外部 API 或无法更改的接口——那么完全的 best 解决方案是修复结构,使其统一,其中类型按键不同。

标签: java json gson


【解决方案1】:

您的问题的一个解决方案是为您的班级写一个TypeAdapter,但是如果您的示例中只有个案例,您可以让 Gson 完成相同的结果您使用最通用的类​​进行反序列化。

我的意思显示在下面的代码中。

package stackoverflow.questions.q19478087;

import com.google.gson.Gson;

public class Q19478087 {

    public class Test {
        public int id;
        public Object blob;
        @Override
        public String toString() {
            return "Test [id=" + id + ", blob=" + blob + "]";
        }


    }

    public static void main(String[] str){
        String json1 = "{\"id\": 1, \"blob\": \"example text\"}";
        String json2 = "{\"id\": 2, \"blob\": {\"to\": 1234, \"from\": 4321, \"name\": \"My_Name\"}}";

        Gson g = new Gson();
        Test test1 = g.fromJson(json1, Test.class);
        System.out.println("Test 1: "+ test1);

        Test test2 = g.fromJson(json2, Test.class);
        System.out.println("Test 2: "+ test2);
    }

}

这是我的处决:

Test 1: Test [id=1, blob=example text]
Test 2: Test [id=2, blob={to=1234.0, from=4321.0, name=My_Name}]

在第二种情况下,blob 将被反序列化为 LinkedTreeMap,因此您可以使用 ((Map) test2.blob).get("to") 访问其元素;

让我知道这是否足够,或者您是否也对类型适配器解决方案感兴趣。

【讨论】:

  • 我写道,blob 将被反序列化为LinkedTreeMap,因此您可以使用((Map) test2.blob).get("to") 访问其元素。也许它没有那么突出,因为我忘记了代码格式。现在它已经修复了。
【解决方案2】:

试试这个

你的 POJO

class FromToName{
    String to;
    String from;
    String name;
    @Override
    public String toString() {
        return "FromToName [to=" + to + ", from=" + from + ", name=" + name
                + "]";
    }
}

您的转换代码

  String json ="{\"id\": 1, \"blob\": \"example text\"}"; 
  //String json = "{\"id\": 2, \"blob\": {\"to\": 1234, \"from\": 4321, \"name\": \"My_Name\"}}";
  Gson gson = new Gson();
  JsonElement element = gson.fromJson (json, JsonElement.class);
  JsonObject jsonObj = element.getAsJsonObject();
  JsonElement id = jsonObj.get("id");
  System.out.println(id);
  if(jsonObj.get("blob") instanceof  JsonPrimitive  ){
         JsonElement blob = jsonObj.get("blob");
         System.out.println(blob);
   }else{
          FromToName blob = gson.fromJson (jsonObj.get("blob"), FromToName.class);
          System.out.println(blob);
   }

如果您对此有任何疑问,请告诉我

【讨论】:

    【解决方案3】:

    将其作为 JSON 元素,然后使用 isMethods() 在运行时确定类型。

    Documentation

            JsonParser jp = new JsonParser();
            JsonElement ele = jp.parse(jsonString).getAsJsonObject().get("blob");;
    
                if (ele.isJsonObject()) {
                      //do related stuff here
                } else if (ele.isJsonArray()) {
                      //do related stuff here
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      • 2017-05-03
      • 2013-01-18
      • 1970-01-01
      • 2018-10-25
      相关资源
      最近更新 更多