如何使用Retrofit解析此错误?


BEGIN_OBJECT,但已BEGIN_ARRAY


Json在下面,它包含一个结果数组对象,该对象具有一个为null的数组对象和一个信息对象。好像是null数组是问题所在,如果需要解决,我需要一些帮助来解决此问题吗?

{
    "error": "OK",
    "limit": 100,
    "offset": 0,
    "number_of_page_results": 16,
    "number_of_total_results": "16",
    "status_code": 1,
    "results": [
        [],
        {
            "api_detail_url"............


型号类别:

 public class Response {

        @SerializedName("results")
        List<IssuesResults> resultList;

        public Response(ArrayList<IssuesResults> resultList) {
            this.resultList = resultList;
        }

        public List<IssuesResults> getResultList() {
            return resultList;
        }
    }


阿皮

@GET("promos/")
Call<Response> getPromos(@Query("api_key") String API_KEY,
                                   @Query("format") String format);


回购

public MutableLiveData<List<IssuesResults>> getPromos() {

    callApi.getPromos(API_KEY,"json").enqueue(new Callback<Response>() {
        @Override
        public void onResponse(Call<Response> call,
                    retrofit2.Response<Response> response) {
            promosMutableData.setValue(response.body().getResultList());

        }

        @Override
        public void onFailure(Call<Response> call, Throwable t) {
            Log.d("PROMOS", "onFailure: " + t);
        }
    });

    return promosMutableData;
}

最佳答案

我假设您使用默认设置的Gson。您的问题是您希望有一个IssuesResults列表,但是它包含这个额外的数组,这意味着-默认情况下-仅可序列化为一个对象列表,该对象列表将是一个数组,并且N个映射为项。

对于这种东西,您需要一些自定义处理,在此我提供一个选项,即JsonDeserializer。我需要进行一些更改以使事情变得容易一些((对于其他方法,它们并不是全部必需品,但对于此解决方案,我将使用这些方法))。首先,而不是内联类型的List实现类,例如:

@SuppressWarnings("serial")
public static class ListIssuesResults extends ArrayList<IssuesResults> {
    // This override is not needed if you do not mind null values in your resulting list
    @Override
    public boolean add(IssuesResults e) {
        if (null != e) {
            return super.add(e);
        }
        return false;
    }
}


更改Response就像:

public static class Response {
    @SerializedName("results")
    private ListIssuesResults resultList;
    // other stuff
}


然后是实际的自定义JsonDeserializer

public static class IssuesResultsDeserializer implements JsonDeserializer<IssuesResults> {
    // this you need to not to cause recursion and stack overflow
    private static final Gson GSON = new Gson();
    @Override
    public IssuesResults deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context)
            throws JsonParseException {
        // this is the trick. if it fails to serialize stuff like [] jsut return null
        try {
            return GSON.fromJson(json, typeOfT);
        } catch (Exception ise) {
            return null;
        }
    }
}


要使用自定义解串器,您需要像这样注册:

new GsonBuilder().registerTypeAdapter(IssuesResults.class,
    new IssuesResultsDeserializer()).create();


这必须在改造客户端构建阶段完成,例如:How to register custom TypeAdapter or JsonDeserializer with Gson in Retrofit?

10-06 02:41