折腾:
【未解决】OkHttp获取响应的body的字符串出错:Exception in thread “main” java.lang.IllegalStateException: closed
期间,发现OkHttp的设计很是垃圾啊,竟然response只能使用一次
导致:连debug打印了一下response,后续都无法继续使用body,以及body的string了。
看到很多提到了:interceptor
貌似可以一劳永逸实现复制一份,供后续使用。
所以去看看:
什么是interceptor
okhttp interceptor
竟然都没写,导入Interceptor的路径。。。真垃圾
好像是okhttp3下面的
果然是:

1 | import okhttp3.Interceptor; |
此处顺带也的确需要去实现log的Interceptor
此处先去解决log的问题:
【已解决】Java中好用的Log日志库
然后再去解决interceptor
【总结】
目前用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import java.io. File ; import java.io.IOException; import java.io.PrintWriter; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.MediaType; import okhttp3.Interceptor; / / import java.io.PrintWriter; / / import PrintWriter; / / import FileUtils; import org.pmw.tinylog.Logger; import org.pmw.tinylog.Level; import org.pmw.tinylog.Configurator; import org.pmw.tinylog.writers.ConsoleWriter; import org.pmw.tinylog.writers.FileWriter; / / public static void saveStrToFile(fullFilePath, strToSave){ / / / / } / / void saveStrToFile(fullFilePath, strToSave){ / / / / } class CrifanUtil { public static void initLogger(String logFilename){ System.out.println( "logFilename=" + logFilename); FileWriter fileWriter = new FileWriter(logFilename); ConsoleWriter consoleWriter = new ConsoleWriter(); Level fileWriterLevel = Level.TRACE; / / Level consoleWriterLevel = Level.DEBUG; Level consoleWriterLevel = Level.INFO; String consoleFormat = "{date:YYMMdd HH:mm:ss} {class}.{method} {{level}|min-size=8}: {message}" ; String fileFormat = "{date:yyyyMMdd HH:mm:ss} [{thread}] {class}.{method} {{level}|min-size=8}: {message}" ; Configurator.currentConfig() .writer(consoleWriter, consoleWriterLevel, consoleFormat) .addWriter(fileWriter, fileWriterLevel, fileFormat) .activate(); / / Logger.trace( "trace" ); / / Logger.debug( "debug" ); / / Logger.info( "info" ); / / Logger.warn( "warn" ); / / Logger.error( "error" ); } } class LoggingInterceptor implements Interceptor { @Override public Response intercept(Interceptor.Chain chain) throws IOException { Request request = chain.request(); long t1 = System.nanoTime(); / / logger.info(String. format ( "Sending request %s on %s%n%s" , / / request.url(), chain.connection(), request.headers())); Logger.info( "Sending request url={} on connection={}, headers={}" , request.url(), chain.connection(), request.headers()); Response response = chain.proceed(request); long t2 = System.nanoTime(); / / logger.info(String. format ( "Received response for %s in %.1fms%n%s" , / / response.request().url(), (t2 - t1) / 1e6d , response.headers())); Logger.info( "Received response for url={} in {}, headers={}" , response.request().url(), (t2 - t1) / 1e6d , response.headers()); return response; } } 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(); } } public class EmulateLoginBaidu { / / OkHttpClient client = new OkHttpClient(); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new LoggingInterceptor()) .addInterceptor(new ResponseInterceptor()) .build(); 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 { String logFilename = "log/EmulateLoginBaidu.log" ; CrifanUtil.initLogger(logFilename); Logger.info( "logFilename={}" , logFilename); Logger.info( "Try Emulate Login Baidu" ); / / Logger.info( "baiduUrl=%s" , baiduUrl); Logger.info( "baiduUrl={}" , baiduUrl); 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); try (PrintWriter printWriter = new PrintWriter( "debug/baidu_com.html" )) { printWriter.println(respBodyStr); } } } |
实现了:
先加log的:LoggingInterceptor
再加重新复制一个response的:ResponseInterceptor
然后最后再去调用
response.body().string()
就不会挂了。