与 (...) 的连接已泄露。您是否忘记关闭响应正文?

2022-09-02 10:46:33

我不断收到警告消息,尽管我的代码似乎很好。消息是:

WARNING: A connection to http://someurl.com was leaked. Did you forget to close a response body?
java.lang.Throwable: response.body().close()
    at okhttp3.internal.platform.Platform.getStackTraceForCloseable(Platform.java:148)
    at okhttp3.RealCall.captureCallStackTrace(RealCall.java:89)
    at okhttp3.RealCall.execute(RealCall.java:73)
    at com.example.HTTPSClientReferenceRate.runClient(HTTPSClientReferenceRate.java:78)
    at com.example.HTTPSClientReferenceRate.main(HTTPSClientReferenceRate.java:137)

我正在使用Java 8。我尝试过传统和这种方法():try-catchtry-with-resources

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    try (Response response = call.execute()){
        if (!response.isSuccessful()) {
            log.error("Error with the response: " + response.message());
            continue;
        }
        ResponseBody body = response.body();
        if (body == null){
            log.error("Error when getting body from the response: " + response.message());
            continue;
        }
        BufferedReader br = new BufferedReader(body.charStream());

        //...DATA HANDLING

    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    }
}

事实上,如果第一行从未被调用,我总是有一个例外,所以我无法理解为什么响应/正文没有被try-with-resources块关闭

我也尝试过这个选项,但它也不起作用:

try (Response response = client.newCall(request).execute()) { ... }

编辑

我已经减少了我的代码,我仍然有同样的错误,这更奇怪:

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    try (Response response = call.execute()){
        //NOTHING
    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    }
}

编辑2

我已经尝试了传统的,但我仍然遇到同样的问题:try-catch

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    Response response = null;
    try {
        response = call.execute();
        try (ResponseBody body = response.body()) {
            //Nothing...
        }
    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    } finally {
        if (response != null){
            response.close();
        }
    }
}

答案 1

根据React.close() javadoc

关闭不符合正文条件的响应是错误的。这包括从 、 和 返回的响应。cacheResponsenetworkResponsepriorResponse()

也许你的代码应该如下所示,根据Github评论

while (repeatRequest) {
    Call call = client.newCall(request);
    Response response = call.execute();
    try (ResponseBody body = response.body()) {
        ...
    }
}

答案 2

使用 Kotlin 时,可以通过关闭 if 它是 non-null 来轻松处理。如果主体存在,则关闭它将关闭源,但如果不存在,则不需要关闭。例如:respoonse.body

                    val response = client.newCall(request).execute()
                    // check for response.isSuccessful here, or read the body if required
                    response.body?.close()

推荐