最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】OkHttp获取响应的body的字符串出错:Exception in thread “main” java.lang.IllegalStateException: closed

Java crifan 1716浏览 0评论
折腾:
【未解决】Java中如何保存字符串到文件中且指定编码
期间,用代码:
import java.io.IOException;
import java.io.PrintWriter;

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

public class EmulateLoginBaidu {
    OkHttpClient client = new OkHttpClient();

    String UserAgent_Mac_Chrome = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36";

//    ResponseBody run(String url) throws IOException {
    Response run(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .header("User-Agent", UserAgent_Mac_Chrome)
                .header("Host", "www.baidu.com")
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
                .header("Cache-Control", "no-cache")
                .build();

        try (Response response = client.newCall(request).execute()) {
//            return response.body().string();
//            return response.body();
            return response;
        }
    }

    public static void main(String[] args) throws IOException {
        System.out.println("Try Emulate Login Baidu");

        String baiduUrl = "http://www.baidu.com";

        EmulateLoginBaidu emulateLogin = new EmulateLoginBaidu();
//        ResponseBody respBody = emulateLogin.run(baiduUrl);
        Response response = emulateLogin.run(baiduUrl);
        System.out.println("response=" + response);
        String respBodyStr = response.body().string();
    }
}
结果
        String respBodyStr = response.body().string();
出错:
Exception in thread "main" java.lang.IllegalStateException: closed
    at okio.RealBufferedSource.rangeEquals(RealBufferedSource.kt:402)
    at okio.RealBufferedSource.rangeEquals(RealBufferedSource.kt:393)
    at okhttp3.internal.Util.bomAwareCharset(Util.java:469)
    at okhttp3.ResponseBody.string(ResponseBody.java:175)
    at EmulateLoginBaidu.main(EmulateLoginBaidu.java:47)
Disconnected from the target VM, address: '127.0.0.1:56071', transport: 'socket'

Process finished with exit code 1
okhttp response body string Exception in thread “main” java.lang.IllegalStateException: closed
okhttp response body string  java.lang.IllegalStateException: closed
okhttp异常: java.lang.IllegalStateException: closed – RickyXE – CSDN博客
okhttp3: java.lang.IllegalStateException: closed – u013023845的博客 – CSDN博客
Okhttp+retrofit遇到的问题:java.lang.IllegalStateException: closed – zkzy28的博客 – CSDN博客
FATAL EXCEPTION: OkHttp Dispatcher · Issue #2593 · square/okhttp
Logging in Retrofit 2.0 · Issue #1072 · square/retrofit
还是去试试:
Response response = emulateLogin.run(baiduUrl);

ResponseBody body = response.body();
String bodyString = body.string();
MediaType contentType = body.contentType();
Response savedResponse = response
        .newBuilder()
        .body(ResponseBody.create(contentType, bodyString))
        .build();

System.out.println("savedResponse=" + savedResponse);
String respBodyStr = savedResponse.body().string();
尝试去用 重新保存的response,去后续多次使用,结果是同样的错误:
又试了:
ResponseBody respBody = response.body();
System.out.println("respBody=" + respBody);

String respBodyStr = respBody.string();
也会导致同样错误
        ResponseBody respBody = response.body();
//        System.out.println("respBody=" + respBody);

        String respBodyStr = respBody.string();
        System.out.println("respBodyStr=" + respBodyStr);
依旧错误。
OkHttp connections do not seem to be closed · Issue #275 · socketio/socket.io-client-java
OkHttp踩坑记:为何 response.body().string() 只能调用一次? – 掘金
OKHttp用法小结,response的巨坑,java.lang.IllegalStateException: closed – zht的博客 – CSDN博客
如果只是用一次,就直接用代码,保证用一次即可
如果想要多次使用,则参考
解决okhttp报java.lang.IllegalStateException: clos… – 简书
去想办法弄那个:intercept
【已解决】拦截器interceptor的作用和如何实现OkHttp的interceptor
【总结】
最后用拦截器:
class ResponseInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        ResponseBody body = response.body();
        String bodyString = body.string();
        MediaType contentType = body.contentType();
        Logger.debug("Response={}", bodyString);
        return response.newBuilder().body(ResponseBody.create(contentType, bodyString)).build();
    }
}


    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new LoggingInterceptor())
        .addInterceptor(new ResponseInterceptor())
        .build();


        EmulateLoginBaidu emulateLogin = new EmulateLoginBaidu();
//        ResponseBody respBody = emulateLogin.run(baiduUrl);
        Response response = emulateLogin.run(baiduUrl);

        ResponseBody respBody = response.body();
        String respBodyStr = respBody.string();
//        String respBodyStr = response.body().string();
        Logger.info("respBodyStr={}", respBodyStr);
可以正常获取
response.body().string()
了。

转载请注明:在路上 » 【已解决】OkHttp获取响应的body的字符串出错:Exception in thread “main” java.lang.IllegalStateException: closed

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.171 seconds, using 22.20MB memory