改进android:gson数组内容反序列化

时间:2015-03-19 06:54:30

标签: android json deserialization retrofit

我在Android上使用Retrofit(1.9.0)和gson库(1.7.0我与gson的2.3.1版本存在兼容性问题)处理API请求,我向API发出了一些请求在url调用之后响应的格式相同但内容不同,但是我遇到了一个内部有数组的一个答案反序列化的问题。这是我要反序列化的json的一个例子:

{
   "http_code":200,
   "content":[
      {
         "name":"Groult Christian",
         "location":[
            48.897655,
            2.252462
         ],
         "website":null,
         "address":{
            "street_address":"XXXXXX",
            "city":"XXXXXX",
            "state":null,
            "postal_code":"XXXXXX",
            "country":"XXXXXX"
         },
         "global_score":0,
         "popularity_score":0,
         "quality_score":0,
         "createdAt":"2015-02-18T02:13:05.068Z",
         "updatedAt":"2015-02-18T02:13:05.068Z",
         "id":"54e3f531775288ca572872ac"
      },
      ...
   ]
}

我的DeserializerJson以及我如何称之为改造:

    public class DeserializerJson<T> implements JsonDeserializer<T> {

        @Override
        public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
                throws JsonParseException
        {
            // Get the "content" element from the parsed JSON
            JsonElement content = je.getAsJsonObject().get("content");

            // Deserialize it. You use a new instance of Gson to avoid infinite recursion
            // to this deserializer
            return new Gson().fromJson(content, type);

        }
    }
...
Gson gson = new GsonBuilder()
                .registerTypeAdapter(ContentUser.class, new DeserializerJson<ContentUser>())
                .registerTypeAdapter(DeviceInfo.class, new DeserializerJson<DeviceInfo>())
                .registerTypeAdapter(PlacesModel.class, new DeserializerJson<PlacesModel>())
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.BASIC)
                .setConverter(new GsonConverter(gson))
                ...
...

和我的不同模特:

public class PlacesModel {
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("location")
    @Expose
    private List<Double> location = new ArrayList<Double>();
    @SerializedName("website")
    @Expose
    private Object website;
    @SerializedName("address")
    @Expose
    private AddressModel address;
    @SerializedName("global_score")
    @Expose
    private Integer globalScore;
    @SerializedName("popularity_score")
    @Expose
    private Integer popularityScore;
    @SerializedName("quality_score")
    @Expose
    private Integer qualityScore;
    @SerializedName("createdAt")
    @Expose
    private String createdAt;
    @SerializedName("updatedAt")
    @Expose
    private String updatedAt;
    @Expose
    @SerializedName("id")
    private String id;

   /* Getters and Setters... */
}

public class AddressModel {

    @SerializedName("street_address")
    @Expose
    private String streetAddress;
    @SerializedName("city")
    @Expose
    private String city;
    @SerializedName("state")
    @Expose
    private Object state;
    @SerializedName("postal_code")
    private String postalCode;
    @SerializedName("country")
    @Expose
    private String country;

    /* Getters and Setters... */
}

在Api Manager中的url调用是这样的:

@GET("/places")
public void getPlaces(RestCallback<List<PlacesModel>> callback);

但是当我拨打电话时出现此错误:com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@3b8aa06 failed to deserialize json object

一切都很好,其他电话我得到所有的内容,所以没有问题,但有一个内容中的数组内容我得到一个错误,我不明白为什么我相信,如果我只是把我的模型列表它会很好,但它不起作用。 如果有人可以帮助我,我想我会想念一些事情

提前致谢

1 个答案:

答案 0 :(得分:1)

您的问题是您为DeserializerJson类注册了PlacesModel,而在getPlaces方法中,您的回复是List<PlacesModel>类。 List<PlacesModel>PlacesModel不同,因此Gson不知道如何反序列化List<PlacesModel>。你要做的是通过这种方法再注册一个Deserialiser:

.registerTypeAdapter(List.class, new DeserializerJson<List<PlacesModel>>())

如果您使用多种类型的List(我的意思是List<PlacesModel>List< DeviceInfo >)您可以定义自己的TypeAdapter或cN更改列表以进行数组和注册他们的反序列化如下所示

.registerTypeAdapter(PlacesModel[].class, new DeserializerJson<PlacesModel[]>())

现在一切都适合你的json。