Retrofit 2 - 使用拦截器时转换的对象为空

Retrofit 2 - Converted object is null when using Interceptor

我正在使用 Interceptor 来查看来自服务器的原始响应:

public WebServiceClient() {
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());
            Log.d(TAG, UtilityMethods.convertResponseToString(response));
            return response;
        }
    });
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://anlatbanaapi.paradoks.biz")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
    tellMeServices = retrofit.create(TellMeServices.class);
}

public Call<GetCategoryResponse> getCategories(){
    Map<String, Object> requestMap = new HashMap<>();
    Long unixTime = System.currentTimeMillis() / LONG_1000;
    requestMap.put(KEY_TIME, unixTime);
    JWTSigner signer = new JWTSigner(SECRET);
    String token = signer.sign(requestMap);
    return tellMeServices.getCategories(token);
}

但是当我使用 Interceptor 时,我得到 null 作为转换对象:

WebServiceClient webServiceClient = new WebServiceClient();
Call<GetCategoryResponse> call = webServiceClient.getCategories();
call.enqueue(new Callback<GetCategoryResponse>() {
    @Override
    public void onResponse(Response<GetCategoryResponse> response, Retrofit retrofit) {
        GetCategoryResponse getCategoryResponse = response.body();

        // Always null if I use Interceptor
        if (getCategoryResponse == null) {
            Log.e(TAG, "Converted response is null!");
            return;
        }

        if (getCategoryResponse.succes == 1) {

            for (Category category : getCategoryResponse.categoryList) {
                Log.d(TAG, category.toString());
            }
        }
        else {
            Log.e(TAG, getActivity().getString(R.string.something_really_bad_happened));
            Toast.makeText(getContext(), R.string.failed_to_get_categories, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onFailure(Throwable t) {
        Log.e(TAG, t.getLocalizedMessage());
    }
});

如果我不使用 Interceptor,我将无法获得原始响应。当我尝试获得原始响应时,出现以下错误:

FATAL EXCEPTION: main
Process: com.yceo.anlatbana, PID: 25656
java.lang.IllegalStateException: Cannot read raw response body of a converted body.
    at retrofit.OkHttpCall$NoContentResponseBody.source(OkHttpCall.java:184)
    at com.squareup.okhttp.ResponseBody.byteStream(ResponseBody.java:43)
    at com.yceo.anlatbana.util.UtilityMethods.convertResponseToString(UtilityMethods.java:126)
    at com.yceo.anlatbana.CategoryFragment.onResponse(CategoryFragment.java:166)
    at retrofit.ExecutorCallAdapterFactory$ExecutorCallback.run(ExecutorCallAdapterFactory.java:86)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5310)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

您只能读取 Response 一次,因为它是一个流。您正在使用 UtilityMethods.convertResponseToString 方法阅读它,因此您需要创建一个具有相同内容的新 Response

client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());
            final String content = UtilityMethods.convertResponseToString(response));
            Log.d(TAG, content);
            return response.newBuilder()
                .body(ResponseBody.create(response.body().contentType(), content))
                .build();
        }
    });