【问题标题】:Retrofit 2 Expected BEGIN_OBJECT but was BEGIN_ARRAY改造 2 预期为 BEGIN_OBJECT,但为 BEGIN_ARRAY
【发布时间】:2016-06-28 19:14:18
【问题描述】:

我有一个如下所示的 JSON 对象:

[[{
    "customers_id": 0
    "name": "John Doe",
    "address": "1234 Merry Way",
    "city": "Miami",
    "zipcode": "55443",
    "state": "Florida"
}, {
    "customers_id": 1
    "name": "John Doe",
    "address": "1234 Merry Way",
    "city": "Miami",
    "state": "Florida"
}, {
    "customers_id": 2
    "name": "John Doe",
    "address": "1234 Merry Way",
    "city": "Miami",
    "state": "Florida"
}],[]

当 Retrofit 返回时,我收到错误 Expected BEGIN_OBJECT but was BEGIN_ARRAY。但是,我的电话设置为返回一个列表:

@POST("search_clients.php")
Call<List<Course>> GetClients();

我的实际改造电话如下所示:

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .build();

ClientLookup clientLookup = retrofit.create(ClientLookup.class);

Call<List<Client>> clients = clientLookup.GetClients();
clients.enqueue(new Callback<List<Client>>() {
    @Override
    public void onResponse(Response<List<Client>> response) {
        if (!response.isSuccess()) {
            Log.e(TAG, "No Success: " + response.message());
             return;
        }

        Log.d(TAG, response.body().toString());
    }

    @Override
    public void onFailure(Throwable t) {
        Log.e(TAG, "Failure: " + t.getMessage());
    }
});

最后我的模型是这样的:

public class Client {
  private int customers_id;
  private String name;
  private String address;
  private String city;
  private String zipcode;
  private String state;
}

最后是一个自定义转换器,用于删除前导 [ 和尾随 ,[]

public final class ClientCleaner extends Converter.Factory {
    private static final String TAG = ClientCleaner.class.getName();

    @Override
    public Converter<ResponseBody, Client> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        return new Converter<ResponseBody, Client>() {
            @Override
            public Client convert(ResponseBody body) throws IOException {
                String returnValue = body.string();
                if (returnValue.startsWith("[")){
                    returnValue = returnValue.substring(1);
                }
                if (returnValue.endsWith(",[]]")){
                    returnValue = returnValue.substring(0, returnValue.length() - 4);
                }
                Log.d(TAG, returnValue);
                Gson gson = new Gson();
                return gson.fromJson(returnValue, Client.class);
            }
        };
    }


}

知道为什么我的电话仍然期待 BEGIN_OBJECT 吗?

【问题讨论】:

  • 原始响应如何?
  • 对不起,这就是我所说的 JSON 对象的意思。 JSON 格式的第一个代码块是响应。虽然它最初包装在另一个数组中。 IE: [[{ "customers_id": 0 "name": "John Doe", "address": "1234 Merry Way", "city": "Miami", "zipcode": "55443", "state": " Florida" }, { "customers_id": 1 "name": "John Doe", "address": "1234 Merry Way", "city": "Miami", "state": "Florida" }],[] 和我使用自定义 ConverterFactory 剥离第一个 [ 和最后一个 ,[]
  • 不,我的意思是你检查 response.raw() 是否真的像你想要的那样?
  • 我更新了我的回复,提供了更多细节。我也无法检查 response.raw,因为它正在抛出 onFailure
  • 所以你有一个自定义的 ConverterFactory,为什么不在问题中?

标签: android retrofit2


【解决方案1】:

列表的反序列化不正确。关于如何使用 Gson 反序列化对象列表,请参阅此 SO question。

这就足够了:

List<Client> videos = gson.fromJson(returnValue, new TypeToken<List<Client>>(){}.getType());

【讨论】:

  • 就是这样,谢谢!发布 ConverterFactory 后,我意识到这可能是导致我的问题的返回值,我只是不知道如何将它作为列表返回。感谢您的洞察力!
猜你喜欢
  • 2019-02-06
  • 1970-01-01
  • 2015-07-24
  • 2014-08-01
  • 2015-11-26
  • 2018-03-27
  • 1970-01-01
  • 2019-03-04
  • 2017-05-16
相关资源
最近更新 更多