Deserialze json with a wrapper keyword with Gson

2019-09-05 00:24发布

问题:

I am using retroft and gson for request/response in my app.
The json structure I get from server for json object is like:

{
"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"
    }
  ]
   }
  }
}

As you see every model is wrapped around data keyword.
For json array response the result is like:

{
"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"
      }
    ]
  }
 }
}

Now I want to Create a class which deserialises theses responses with GSON, but I can't implement JsonDeserializer<DataObjectModel> since in the deserialize method I don't know wheter to call je.getJsonObject("data") or je.getJsonArray("data"). How to deserialize this response?

回答1:

"data" is a JSON array, that's why you need to use je.getJsonArray("data").

If you are using retrofit, then you can deserialise this JSON in POJO with a help of GSON Converter Factory. POJO you can create with a help of this site: http://www.jsonschema2pojo.org/

Good tutorial on retrofit for your needs is here: https://guides.codepath.com/android/Consuming-APIs-with-Retrofit



回答2:

Create a POJO class for the response i.e create a model class and use the @SerializedName annotation like below

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

And to deserialize all you have to do is use the below code

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

Let me know if you have any doubts.



回答3:

Make two gson model classes -

    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:

its perfectly fine to do:

@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
            }
            ...