使用OkHttp3发送Delete请求抛出java.io.InterruptedIOException问题求助
解决OkHttp3 Delete请求抛出
java.io.InterruptedIOException: interrupted的问题 首先,从你的调用栈日志里能一眼抓到关键线索:这个Delete请求是在WebSocket的onClose回调方法里触发的!这就是问题的核心所在。
问题根源分析
Tomcat的WebSocket容器处理onClose回调时,用的是和WebSocket会话绑定的专属线程。当会话关闭流程走完后,这个线程会被容器中断甚至回收。而你的runDelete方法里用了OkHttp的同步execute()——这个方法会阻塞当前线程直到请求完成。当执行请求的线程(也就是WebSocket的回调线程)被容器中断时,OkHttp正在进行的IO操作就会抛出InterruptedIOException: interrupted异常。
简单说:你的网络请求和WebSocket回调线程的生命周期绑定死了,线程被干掉,请求自然中途夭折。
解决方案
有两种靠谱的解决方式,根据你的业务场景选:
1. 改用OkHttp异步请求(推荐)
把同步的execute()换成异步的enqueue(),让请求在OkHttp自己维护的线程池里执行,完全脱离WebSocket回调线程的生命周期。
修改你的请求方法:
public void runDeleteAsync(String url, String token, Object sendRequest, okhttp3.Callback callback) { try { RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), JSON.toJSONString(sendRequest)); Request request = new Request.Builder() .url(url) .delete(requestBody) .addHeader("token", token) .build(); httpClient.newCall(request).enqueue(callback); } catch (Exception e) { log.error("调用delete失败", e); callback.onFailure(null, e); } }
然后在WebSocket的onClose里调用异步方法:
// 在你的WebSocketClientEndpoint.onClose方法中 runDeleteAsync( "你的目标URL", token, sendRequest, new okhttp3.Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { log.error("异步Delete请求失败", e); } @Override public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException { try (response) { // 自动关闭response资源 if (response.isSuccessful()) { String result = response.body().string(); // 这里处理请求结果 } else { log.error("Delete请求返回错误状态码: {}", response.code()); } } } } );
2. 用独立线程池执行同步请求
如果你的业务逻辑必须用同步请求,那就把请求放到你自己维护的线程池里执行,别用WebSocket的回调线程:
// 先定义一个全局的线程池(比如在Spring里用@Bean注入) private ExecutorService requestThreadPool = Executors.newFixedThreadPool(5); // 包装原有同步方法 public void runDeleteInSeparateThread(String url, String token, Object sendRequest) { requestThreadPool.submit(() -> { String result = runDelete(url, token, sendRequest); // 调用你原来的同步方法 // 在这里处理返回结果 }); }
然后在onClose里调用这个包装后的方法即可。
额外注意点
- 务必保证
OkHttpClient是全局单例的,不要每次请求都新建实例,否则会快速耗尽系统线程资源。 - 检查你的
OkHttpClient超时配置,虽然这次的异常不是超时导致的,但合理的超时设置能避免请求无意义地阻塞。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

