You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android报错java.lang.IllegalStateException: 无法读取已转换响应体的原始内容

问题:Retrofit同步数据时崩溃,报错java.lang.IllegalStateException: Cannot read raw response body of a converted body

在使用Retrofit将数据同步到服务器时,应用持续崩溃,报错信息如上。相关代码和Logcat日志如下:

出错代码

private void uploadToServer(String date, String userid, JSONArray attachment, String expense, String ad_user, String ad_pass, String versionCode, String apiVersion, String dcrSync, String urlParameters) {
   RequestBody description = RequestBody.create(MediaType.parse("text/plain"), attachment.toString());
APIinterface apIinterface = RetrofitClient.getRetrofitClient(getApplicationContext()).create(APIinterface.class);
    final Call<ResponseBody> call = apIinterface.uploadExpenseData(Datafields.tag_url.get("expense_sync").toString(), date, userid, attachment.toString(), expense, ad_user, ad_pass, versionCode, apiVersion, dcrSync);
Log.e("attachement", attachment.toString());
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.e("syncObjetc", String.valueOf(response));
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                String url = response.raw().request().url().toString();
                ResponseBody body = response.raw().body();
                try {
                    Toast.makeText(Sync.this, responseBody.string(), Toast.LENGTH_SHORT).show();
                    Toast.makeText(Sync.this, body.string(), Toast.LENGTH_SHORT).show();

                    progressDialog.dismiss();
                    JSONObject jsonObject = new JSONObject(response.body().string());
                    JSONObject messageObj = jsonObject.getJSONObject("message");
                    JSONObject codeObject = jsonObject.getJSONObject("code");
                    JSONObject syncObjetc = jsonObject.getJSONObject("synchData");
                    String message = messageObj.getString("message");
                    int code = codeObject.getInt("code");
                    String date = syncObjetc.getString("date");
                    Log.e("String message ", message);
                    Log.e("syncObjetc", String.valueOf(syncObjetc));
                    Log.e("resbody ", responseBody.string());

                    altDialog.setMessage(message);
                    altDialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startActivity(new Intent(Sync.this, Sync.class));
                            overridePendingTransition(0, 0);
                        }
                    });
                    altDialog.show();
                    if (code == 0) {
                        syncExpense(date);
                    }


                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            progressDialog.dismiss();
            Toast.makeText(Sync.this, "Sync Failed", Toast.LENGTH_LONG).show();
            Log.e("Faliure", t.getMessage());
        }
    });
}

Logcat日志

java.lang.IllegalStateException: Cannot read raw response body of a converted body.
        at retrofit2.OkHttpCall$NoContentResponseBody.source(OkHttpCall.java:274)
        at okhttp3.ResponseBody.string(ResponseBody.java:173)
        at com.anantfso.glenmark_fso_demo.Sync$19.onResponse(Sync.java:1898)
        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$1.run(DefaultCallAdapterFactory.java:83)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2023-04-24 12:58:48.459 9893-9893/com.anantfso.glenmark_fso_demo W/System.err: java.lang.IllegalStateException: Cannot read raw response body of a converted body.
2023-04-24 12:58:48.459 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at retrofit2.OkHttpCall$NoContentResponseBody.source(OkHttpCall.java:274)
2023-04-24 12:58:48.459 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at okhttp3.ResponseBody.string(ResponseBody.java:173)
2023-04-24 12:58:48.459 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at com.anantfso.glenmark_fso_demo.Sync$19.onResponse(Sync.java:1898)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$1.run(DefaultCallAdapterFactory.java:83)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at android.os.Handler.handleCallback(Handler.java:883)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:100)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at android.os.Looper.loop(Looper.java:214)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7356)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
2023-04-24 12:58:48.460 9893-9893/com.anantfso.glenmark_fso_demo W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

崩溃原因

  • Retrofit中,调用response.body()获取转换后的响应体时,原始响应体(response.raw().body())已被Retrofit处理并关闭,无法再次读取,强行读取就会触发该异常
  • ResponseBody.string()方法会一次性消耗响应体的输入流,第二次调用时流已关闭,同样会抛出异常。代码中多次调用responseBody.string()、response.body().string(),导致重复消耗流
  • 同时混用response.body()和response.raw().body(),既读取转换后的响应体,又尝试读取已被处理的原始响应体,触发了Retrofit的保护机制

解决方法

核心思路

只读取一次响应体内容并缓存,后续所有操作都使用缓存的字符串,同时不要调用response.raw().body()。

修改后的代码

private void uploadToServer(String date, String userid, JSONArray attachment, String expense, String ad_user, String ad_pass, String versionCode, String apiVersion, String dcrSync, String urlParameters) {
   RequestBody description = RequestBody.create(MediaType.parse("text/plain"), attachment.toString());
APIinterface apIinterface = RetrofitClient.getRetrofitClient(getApplicationContext()).create(APIinterface.class);
    final Call<ResponseBody> call = apIinterface.uploadExpenseData(Datafields.tag_url.get("expense_sync").toString(), date, userid, attachment.toString(), expense, ad_user, ad_pass, versionCode, apiVersion, dcrSync);
Log.e("attachement", attachment.toString());
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.e("syncObjetc", String.valueOf(response));
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                String url = response.raw().request().url().toString();
                // 只读取一次响应体内容并缓存
                String responseContent = "";
                try {
                    if (responseBody != null) {
                        responseContent = responseBody.string();
                    }

                    Toast.makeText(Sync.this, responseContent, Toast.LENGTH_SHORT).show();
                    progressDialog.dismiss();
                    
                    JSONObject jsonObject = new JSONObject(responseContent);
                    JSONObject messageObj = jsonObject.getJSONObject("message");
                    JSONObject codeObject = jsonObject.getJSONObject("code");
                    JSONObject syncObjetc = jsonObject.getJSONObject("synchData");
                    String message = messageObj.getString("message");
                    int code = codeObject.getInt("code");
                    String syncDate = syncObjetc.getString("date");
                    
                    Log.e("String message ", message);
                    Log.e("syncObjetc", String.valueOf(syncObjetc));
                    Log.e("resbody ", responseContent);

                    altDialog.setMessage(message);
                    altDialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startActivity(new Intent(Sync.this, Sync.class));
                            overridePendingTransition(0, 0);
                        }
                    });
                    altDialog.show();
                    if (code == 0) {
                        syncExpense(syncDate);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            progressDialog.dismiss();
            Toast.makeText(Sync.this, "Sync Failed", Toast.LENGTH_LONG).show();
            Log.e("Failure", t.getMessage());
        }
    });
}

关键修改点

  • 新增responseContent变量,一次性读取响应体内容,后续所有操作都使用这个变量
  • 移除了对response.raw().body()的调用和读取
  • 把所有原本调用ResponseBody.string()的地方替换为使用responseContent
  • 变量名date重命名为syncDate,避免和方法参数的date冲突

内容的提问来源于stack exchange,提问作者Abm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:44:52