OKHttp响应失败:java.lang.IllegalStateException: closed

15

我请求提供链接以获取JSON,但response.body().string()的值总是出现错误。另一种方式是将response.body().string()拆分为response.body()和string,但Android studio找不到ResponseBody。这两种方式都不起作用。请帮忙!

String doGetRequest(String url) throws IOException {
       Request request = new Request.Builder()
            .url(url)
            .build();

    try (Response response = client.newCall(request).execute()) {
        System.out.println(response.body().string());
        //ResponseBody responseBody = response.body();
        //String content = responseBody.string();
        //System.out.println(content);
        return response.body().string();
    }
}
3个回答

26

response.body().string() → 您只能调用一次string()。

由于响应体可能非常庞大,因此OkHttp不会将其存储在内存中,而是在需要时从网络中读取它作为流。

当您将body作为string()读取时,OkHttp会下载响应体并返回给您,但不会保留该字符串的引用,因此它不能在未进行新请求的情况下再次下载。

您正在多次调用它。

try(..){
    System.out.println(response.body().string());// once
    return response.body().string();`// twice
 }

你可以调用一次响应并将其保存在变量中,然后将该变量用于进一步的使用。

try(..){
  String responseData = response.body().string();//Be cautious about memory constraint here.
  System.out.println(responseData);
  return responseData;`
}

1
我在调试模式下看到了这个问题,但是我使用了ResponseBody并将其转换为字符串。同样的错误再次出现了。后来我找到了一种新的解决方法。我关闭了响应,例如response.close();,这解决了我的问题。 - Kamil
即使在代码运行之前从调试器中调用它.string() ‍♂️。 - Austin

11

这种情况是因为.string()只能被调用一次。

您可以按照以下方式解决此问题(Java):

ResponseBody responseBodyCopy = response.peekBody(Long.MAX_VALUE);
responseBodyCopy.string();

通过复制响应主体,您可以避免两次使用.string()方法。


1
也许你正在像这样在拦截器中关闭响应:
override fun intercept(chain: Interceptor.Chain): Response {
//...
val response = chain.proceed(builder.build())
response.close()
//...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接