【问题标题】:OkHttp3 response.body().string() always returns emptyOkHttp3 response.body().string() 总是返回空
【发布时间】:2020-08-19 07:45:38
【问题描述】:

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.Reader;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class MainActivity extends AppCompatActivity {

    TextView title;
    TextView instructions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        title = findViewById(R.id.titleView);
        instructions = findViewById(R.id.instructionsView);

        OkHttpClient client = new OkHttpClient();

        String url = "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/findByIngredients?number=1&ranking=1&ignorePantry=false&ingredients=apple%252Csugar%252Csalt";
        Request request = new Request.Builder()
                .url(url)
                .get()
                .addHeader("x-rapidapi-host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
                .addHeader("x-rapidapi-key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    String myResponse = response.body().string();
                    Log.i("string", myResponse);
                }
            }
        });
    }
}

.toString() 的日志输出:2020-05-04 19:55:51.801 9894-10024/com.example.testapi I/string: okhttp3.internal.http.RealResponseBody@6314479

.string() 的日志输出:2020-05-04 20:00:39.430 10118-10143/com.example.testapi I/string: []

我知道 OkHttp3 如何在第一次调用 .body() 后立即清空支持资源,但它对我来说仍然是空的。

我该如何解决这个问题?

【问题讨论】:

  • 请尝试在调试模式下运行并检查响应。这不是日志
  • Response{protocol=http/1.1, code=200, message=OK, url=spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/…} 这是我检查响应时得到的。
  • 是预期响应吗?
  • 据我所知,是的。我得到 200 响应代码,这意味着连接成功。字符串应该保持身体。之前没有对身体的呼唤,所以它应该还在那里。但事实并非如此。
  • 当您尝试使用 curl 或 postman 进行相同的调用时,您会得到哪个答案?

标签: java android json okhttp


【解决方案1】:

调用response.body().string() 会消耗身体 - 因此,您不能第二次调用它。在 您的 sn-p 之外的代码 中,必须至少有一个 response.body() 离开。

响应正文只能使用一次。

https://square.github.io/okhttp/3.x/okhttp/index.html?okhttp3/ResponseBody.html

修复

在您的实现代码中,response.body() 已经被调用过一次。而是替换为response.peekBody()

如果需要进一步处理,解决方案是将其存储在变量中。

         @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    String myResponse = response.peekBody(99999L).string();
                    Log.i("string", myResponse);
                }
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 2022-11-10
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多