解决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();语句。

最后分享一句话:
勤學如春起之苗,不見其增,日有所長。綴學如磨刀之石,不見其損,日有所虧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值