【问题标题】:Retrofit 2 - Manage http "204 No content" and "200" with content for the same requestRetrofit 2 - 使用相同请求的内容管理 http“204 无内容”和“200”
【发布时间】:2018-06-20 00:09:04
【问题描述】:

我正在使用 Retrofit 2 和 OkHttp 3,以及 RxJava2

我正在使用一些参数调用服务器。根据参数,服务器返回一个带有对象列表的 JSON。但是,如果没有要返回的内容,服务器不会返回带有空列表的 JSON,而是返回“204 - 无内容”。结果我得到一个 NullPointerException。

我知道如何管理 JSON 响应,并且我知道如何管理 204 响应,但不会一起处理同一个调用。

我可以使用拦截器,但由于我有很多调用,我的 Retrofit 客户端只创建一次,然后在必要时使用 Dagger2 注入。

我该如何处理这种情况?

【问题讨论】:

  • 尝试使用 Observable.onErrorResumeNext(throwable -> empty())

标签: android retrofit2 dagger-2 rx-java2 okhttp3


【解决方案1】:

我使用 onErrorResumeNext 进行错误响应。例如

mSubscription.add(mViewModel.getMyPohybyFromSqlServer("3", drupoh)
            .subscribeOn(Schedulers.computation())
            .observeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
            .doOnError(throwable -> { Log.e(TAG, "Error xxx " + throwable.getMessage());
                hideProgressBar();
                Toast.makeText(getActivity(), "Server not connected", Toast.LENGTH_SHORT).show();
            })
            .onErrorResumeNext(throwable -> empty())
            .subscribe(this::setPohyby));

【讨论】:

  • 感谢您的回答。但我想做的是改造调用 onSuccess 因为它不应该是一个错误。因为目前没有内容时可抛出的类型是NullPointerException,所以我可以按照你的建议恢复错误但NullPointerException也可能是由代码中的错误引起的,所以我觉得考虑它很危险仅表示内容为空。
【解决方案2】:

根据@eurosecom 的建议,我已经解决了我的问题,如下所述。唯一的问题是我希望来自服务器的“无内容”响应由 Retrofit 管理为“成功”,但使用此解决方案仍将其作为错误进行管理。

改造客户端

return new OkHttpClient.Builder()
    .addInterceptor(new GeneralInterceptor(callback))
    .build


private static class GeneralInterceptor implements Interceptor {

    //... 

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder();
        Response response = chain.proceed(requestBuilder.build());

        // Throw specific Exception on HTTP 204 response code
        if (response.code() == 204) {
            throw new NoContentException("There is no content");
        }

        return response; // Carry on with the response
    }
}

在演示者中

mModel.performRequest()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onErrorResumeNext(throwable -> {
        if (throwable instanceof NoContentException) {
            return Observable.empty();
        }

        return Observable.error(throwable);
    })
    .subscribe(res -> {
        //... Manage the result
    }, throwable -> {
        //... On error
    }
);

【讨论】:

  • 我不会将此答案标记为已接受,因为它不符合问题要求。如果有人有更好的解决方案,我将不胜感激。
  • 您的解决方案很好,将此答案标记为已接受。我已经阅读了有关在 RxJava 2.0 medium.com/@joshfein/handling-null-in-rxjava-2-0-10abd72afa0b 中处理 null 的有趣文章可能会有所帮助,但我没有对其进行测试。
  • 如果我记得 NullPointerException 来自 Gson 解析器,因为它预期某些内容并且内容为空。但它实际上可以为我的应用程序的另一部分提供帮助,因为我已经不得不面对您链接的文章中描述的问题。谢谢你的帮助!然后我会将答案标记为已接受。
  • 为什么不返回修改后的响应对象(使用response.newBuilder())并更改响应代码并添加一个空正文? if (response.code() == 204) { response = response.newBuilder() .code(200) .body(ResponseBody.create(MediaType.parse("application/json"), "[]")) .build() } ?
猜你喜欢
  • 2018-07-11
  • 2022-10-18
  • 1970-01-01
  • 2010-09-06
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 2023-03-23
相关资源
最近更新 更多