【问题标题】:Deserialze json with a wrapper keyword with Gson使用 Gson 使用 wrapper 关键字反序列化 json
【发布时间】:2016-04-05 08:08:58
【问题描述】:

我在我的应用程序中使用retroftgson 进行请求/响应。
我从服务器获取的 json 对象的 json 结构如下:

{
"data": {
"name": "Rogelio Volkman",
"address": "27299 Will Bridge Suite 058\nWest Reubenhaven, MI 00736",
"lat": 54.65,
"lng": 111.75,
"phone": "+26(4)5015498663",
"user": {
  "data": [
    {
      "name": "Mehrdad"
    }
  ]
   }
  }
}

如您所见,每个模型都围绕着 data 关键字。
对于 json 数组响应,结果如下:

{
"data": [
{
  "name": "Rogelio Volkman",
  "address": "27299 Will Bridge Suite 058\nWest Reubenhaven, MI 00736",
  "lat": 54.65,
  "lng": 111.75,
  "phone": "+26(4)5015498663",
  "user": {
    "data": [
      {
        "name": "Mehrdad"
      }
    ]
  }
},
{
  "name": "Jovani Ritchie",
  "address": "920 Winona Lake\nAlisashire, GA 27145",
  "lat": -32.57,
  "lng": 134.6,
  "phone": "442.530.4166",
  "user": {
    "data": [
      {
        "name": "Mehrdad"
      }
    ]
  }
 }
}

现在我想创建一个使用 GSON 反序列化这些响应的类,但我不能 implement JsonDeserializer<DataObjectModel> 因为在 deserialize 方法中我不知道该调用 je.getJsonObject("data") 还是 je.getJsonArray("data") . 如何反序列化这个响应?

【问题讨论】:

    标签: java android json gson retrofit2


    【解决方案1】:

    "data" 是一个 JSON 数组,所以你需要使用 je.getJsonArray("data")。

    如果您正在使用改造,那么您可以在 GSON Converter Factory 的帮助下在 POJO 中反序列化这个 JSON。 您可以在此站点的帮助下创建 POJO:http://www.jsonschema2pojo.org/

    关于根据您的需要进行改造的好教程在这里:https://guides.codepath.com/android/Consuming-APIs-with-Retrofit

    【讨论】:

    • 没有先阅读问题就回答了我的问题?我要求使用 data 关键字进行反序列化
    • @Mehrdad,我很抱歉,但你的写作风格让我很困惑,很难理解你在问题中真正想要什么。不过,您可以使用我的回答中描述的方法,它会毫无问题地工作。
    【解决方案2】:

    为响应创建一个 POJO 类,即创建一个模型类并使用 @SerializedName 注释,如下所示

    public class Data{
      @SerializedName("name")
       String name;
      @SerializedName("address")
       String address;
      @SerializedName("lat")
       double lat;
       .....
    } 
    

    要反序列化你所要做的就是使用下面的代码

      String dataString = responseObject.getString("data");
      Data[] dataArray = new Gson().fromJson(dataString,Data[].class);
    

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

    【讨论】:

    • 没关系,但由于我使用的是retrofit,数据是在回调方法中处理的,所以我无法像普通的String一样访问响应
    • 你得到了改造权的 jsonObject 响应。你可以使用 object.toString();
    【解决方案3】:

    制作两个 gson 模型类 -

        Class UserObject {
            @SerializedName("data")
            User user;
        }
        Class User {
            // User object
        }
        Class UserArray {
             @Serialized("data")
             User[] list;
        }
    
        Object json = new JSONTokener(data).nextValue();
        if (json instanceof JSONObject) {
          //you have an object
           new Gson().fromJson(json,UserObject.class); 
        } else if (json instanceof JSONArray) {
           new Gson.fromJson(json,UserArray.class);
        }
    

    【讨论】:

      【解决方案4】:

      完全没问题:

      @Override
              public DataObjectModel deserialize(JsonElement json, Type type,
                                                 JsonDeserializationContext context) throws JsonParseException {
      
                  JsonElement data = ((JsonObject) json).get("data");
                  if(data.isJsonArray()) {
                     JsonArray dataArr = data.getAsJsonArray();
                      //do smth with array
                  } else {
                      JsonObject dataObj = data.getAsJsonObject();
                      //do smth with object
                  }
                  ...
      

      【讨论】:

      • 如何为模型的List 数据类型注册解串器类。我试过new GsonBuilder().registerTypeHierarchyAdapter(Museum.class, new DataObjectDeserializer()).registerTypeAdapter(Museum[].class, new DataObjectDeserializer()).create(); 但没用
      • 究竟什么没用?您需要在创建“GsonConverterFactory.create(gson)”时将创建的 gson 传递给转换器工厂
      猜你喜欢
      • 2012-07-13
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多