【问题标题】:Retrofit android: gson array content deserialization改造android:gson数组内容反序列化
【发布时间】:2015-03-22 03:17:02
【问题描述】:

我正在 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

对于其他调用来说一切都很好我得到了所有内容,所以没有问题,但是在内容中有数组的地方我得到了一个错误,我不明白为什么我相信如果我只是把我的模型列表它会没关系,但它不起作用。 我想我想念一些东西,所以如果有人可以帮助我

提前致谢

【问题讨论】:

  • 这是完整的堆栈跟踪吗?如果不是,请在您的问题中发布完整的堆栈跟踪。
  • 是的,它几乎是完整的堆栈跟踪,在这个错误之后只有我想要反序列化的 json
  • 堆栈跟踪中是否有行号显示导致JsonParseException的部分代码?
  • 不,但这是在失败函数中显示的消息:apiManager.getPlaces(new RestCallback&lt;List&lt;PlacesModel&gt;&gt;() { @Override public void failure(RestError restError) { Log.d("TEST", restError.getStrMessage()); } @Override public void success(List&lt;PlacesModel&gt; placesModels, Response response) { Log.d("TEST", "test"); } });
  • @flo3573358 我解决了您的问题,如果可行,请通知我

标签: android json deserialization retrofit


【解决方案1】:

您的问题是您为PlacesModel 类注册了DeserializerJson,而在getPlaces 方法中您的响应是List&lt;PlacesModel&gt; 类。 List&lt;PlacesModel&gt;PlacesModel 是不同的类,所以 Gson 不知道如何反序列化 List&lt;PlacesModel&gt;。您要做的就是通过这种方法再注册一个反序列化器:

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

如果您使用不止一种类型的List(我的意思是List&lt;PlacesModel&gt;List&lt; DeviceInfo &gt;),您可以定义自己的TypeAdapter,或者您可以将列表更改为数组并为它们注册反序列化器,如下所示

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

现在你的 json 一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    相关资源
    最近更新 更多