解决okhttp3提示java.lang.IllegalStateException:closed异常问题
作者:一缕纯氧
使用OkHttp3时,response.body().string()只能调用一次,重复调用会导致流关闭异常,解决方法是保存响应体内容到变量或重新构建Response对象,避免多次读取
okhttp3提示java.lang.IllegalStateException:closed异常
使用okhttp3的response.body().string()时候提示java.lang.IllegalStateException: closed异常
原因为okhttp3请求回调中response.body().string()只能有效调用一次,而我使用了两次,所以在第二次时调用时提示已关闭流的异常。
Response response = httpClient.newCall(request).execute(); logger.info(response.body().string()); //一次 Map<String,Object> resMap=objectMapper.readValue(response.body().string(),Map.class); //两次
解决办法
将返回的值保存在对象中,重复使用对象即可。(或者重新builder一个Response对象)
public void pushOrder(RecordPushRequest pushRequest) throws Exception { //TODO:构造builder Request.Builder builder = new Request.Builder() .url(URL) .header("Content_Type", "application/json"); //TODO:构造请求体 RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), objectMapper.writeValueAsString(pushRequest)); //TODO:构造请求 Request request = builder.post(requestBody).build(); //TODO:发起请求 Response response = httpClient.newCall(request).execute(); String res = response.body().string(); // logger.info(response.body().string()); //打印时重复使用了一次 Map<String,Object> resMap=objectMapper.readValue(res,Map.class); logger.info("得到的响应解析结果:{} ",resMap); }
深扒response.body().string()问题原因
查看源码Response.class:
private final ResponseBody body;
发现body是一个ResponseBody 对象。继续查看ResponseBody 类的源码:
public abstract class ResponseBody implements Closeable
ResponseBody类实现Closeable接口,感觉有点找到问题的源泉了,继续点进去看看Closeable接口是干嘛的:
public interface Closeable extends AutoCloseable { /** * Closes this stream and releases any system resources associated * with it. If the stream is already closed then invoking this * method has no effect. * * <p> As noted in {@link AutoCloseable#close()}, cases where the * close may fail require careful attention. It is strongly advised * to relinquish the underlying resources and to internally * <em>mark</em> the {@code Closeable} as closed, prior to throwing * the {@code IOException}. * * @throws IOException if an I/O error occurs */ public void close() throws IOException; }
Closeable接口继承AutoCloseable类,有一个close方法,官方标注:“关闭此流并释放与之关联的任何系统资源。
如果流已关闭,则调用此方法无效。”大概就是这个原因了。所以不要多次调用response.body().string();语句。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。