Catherine's blog

Knowledge makes humble, ignorance makes proud.

0%

OKHttp-leaked

使用OKHttp 3時,一直收到Leaked 的警告,上網了解後才發現需要關閉流,以下為錯誤造成的原因,以及修正的方法

你將發現Eclipse一直提醒

1
2
六月 08, 2020 9:20:45 上午 okhttp3.internal.platform.Platform log
警告: A connection to http:// / was leaked. Did you forget to close a response body? To see where this was allocated, set the OkHttpClient logger level to FINE: Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.FINE);

以下為錯誤寫法

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
private String sendECPost(String requestUrl, String data) throws ServerUnableException {
String conyentType = Constants.CONTENT_TYPE_JSON;
log.info("conyentType :" + conyentType);

OkHttpClient client = new OkHttpClient().newBuilder().sslSocketFactory(createSSLSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}).build();

MediaType mediaType = MediaType.parse(conyentType);
okhttp3.RequestBody requestBody = okhttp3.RequestBody.create(mediaType, data);
Request request = new Request.Builder().url(requestUrl).post(requestBody).build();
String responseStr = null;
Call call = client.newCall(request);
try {
Response response = call.execute();
log.info(response);
if (!response.isSuccessful()) {
log.info("response error msg: " + response.message());
throw new CustomException.ServerUnableException();
} else {
responseStr = response.body().string().replace("\n", "");
response.body().close();
}

} catch (IOException e) {
log.error(e);
}

return responseStr;
}

該如何解決這個問題呢?在response code=200也就是正常的狀況下,都會調用.string()來關閉流,但是若不是此情況,將不會關閉,因此造成leaked,那我們只需在非正常狀況下也關掉流即可,程式碼如下:

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
private String sendECPost(String requestUrl, String data) throws ServerUnableException {
String conyentType = Constants.CONTENT_TYPE_JSON;
log.info("conyentType :" + conyentType);

OkHttpClient client = new OkHttpClient().newBuilder().sslSocketFactory(createSSLSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}).build();

MediaType mediaType = MediaType.parse(conyentType);
okhttp3.RequestBody requestBody = okhttp3.RequestBody.create(mediaType, data);
Request request = new Request.Builder().url(requestUrl).post(requestBody).build();
String responseStr = null;
Call call = client.newCall(request);
try {
Response response = call.execute();
log.info(response);
if (!response.isSuccessful()) {
log.info("response error msg: " + response.message());
throw new CustomException.ServerUnableException();
response.body().close();
} else {
responseStr = response.body().string().replace("\n", "");
response.body().close();
}

} catch (IOException e) {
log.error(e);
}

return responseStr;
}

OkHttp:避免泄漏连接警告

Welcome to my other publishing channels