如何处理 Retrofit 2 中错误的不同模式?

我有一个返回以下模式之一的 API:


成功(找到数据)


{

    item_count: 83,

    items_per_page: 25,

    offset: 25,

    items: [

        { ... },

        { ... },

        { ... },

        ...

    ]

}

失败(未找到数据)


{

    success: false,

    error: {

        code: 200,

        message: "Server is busy"

    }

}

我想使用带有 GSON 的 Retrofit 2 来围绕这个 API 构建一个包装器并转换为 POJO,但是我不确定如何处理 API 可能返回两个完全不同的模式的事实。现在,我有以下课程:


public class PaginatedResponse<T> {

    private int item_count;

    private int items_per_page;

    private int offset;

    private List<T> items;


    public PaginatedResponse<T>(int item_count, int items_per_page, int offset, List<T> items) {

        this.item_count = item_count;

        this.items_per_page = items_per_page;

        this.offset = offset;

        this.items = items;

    }


    public List<T> getItems() {

        return this.items;

    }

}

public class Item {

    private int id;

    private String name;

    // ...

}

然后对于我的 API 接口,我有:


public interface API {

    @GET("items")

    Call<PaginatedResponse<Item>> getItems();

}

然后最后用这个我试着说:


Retrofit retrofit = new Retrofit.Builder()

    .baseUrl("http://localhost")

    .addConverterFactory(GsonConverterFactory.create())

    .build();


API api = retrofit.create(API.class);


api.getItems().enqueue(new retrofit2.Callback<PaginatedResponse<Broadcast>>() {

    @Override

    public void onResponse(Call<PaginatedResponse<Broadcast>> call, Response<PaginatedResponse<Broadcast>> response) {

        Log.d("SUCCESS", response.body().getItems().toString());

    }


    @Override

    public void onFailure(Call<PaginatedResponse<Broadcast>> call, Throwable t) {

        Log.d("FAILURE", t.toString());

    }

}

只要没有抛出错误,这似乎就可以了。但是当抛出错误时,我在 Logcat 中得到以下信息并且我的应用程序崩溃:


java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

似乎是因为失败的 JSON 缺少一个items属性,它设置List<Item> items为null


四季花海
浏览 119回答 1
1回答

胡子哥哥

似乎是因为失败的 JSON 缺少 items 属性,它将 List items 设置为 null是的。你得到了NullPointerException,因为你调用toString()了一个空对象。这是预期的行为。解决方案error由于和具有不同的模式success,因此您需要创建一个具有这两个值的模型。下面给出一个最小的例子,响应模型.javaclass ResponseModel {&nbsp; &nbsp; // ERROR&nbsp; &nbsp; private final Boolean success;&nbsp; &nbsp; private final Error error;&nbsp; &nbsp; // SUCCESS&nbsp; &nbsp; private final int item_count;&nbsp; &nbsp; // more success values...&nbsp;&nbsp; &nbsp; ResponseModel(Boolean success, Error error, int item_count) {&nbsp; &nbsp; &nbsp; &nbsp; this.success = success;&nbsp; &nbsp; &nbsp; &nbsp; this.error = error;&nbsp; &nbsp; &nbsp; &nbsp; this.item_count = item_count;&nbsp; &nbsp; }&nbsp; &nbsp; public class Error {&nbsp; &nbsp; &nbsp; &nbsp; private final int code;&nbsp; &nbsp; &nbsp; &nbsp; private final String message;&nbsp; &nbsp; &nbsp; &nbsp; private Error(int code, String message) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.code = code;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.message = message;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public int getCode() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return code;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public String getMessage() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return message;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public Boolean getSuccess() {&nbsp; &nbsp; &nbsp; &nbsp; return success;&nbsp; &nbsp; }&nbsp; &nbsp; public Error getError() {&nbsp; &nbsp; &nbsp; &nbsp; return error;&nbsp; &nbsp; }&nbsp; &nbsp; public int getItem_count() {&nbsp; &nbsp; &nbsp; &nbsp; return item_count;&nbsp; &nbsp; }}在onResponse方法中,您可以像这样检查响应是否成功ResponseModel responseModel = response.body();if (responseModel.getError() == null) {&nbsp; &nbsp; // success&nbsp; &nbsp; doSomethingWithSuccess(responseModel.getItem_count())} else {&nbsp; &nbsp; // error&nbsp; &nbsp; doSomethingWithError(responseModel.getError())}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java