eclipse "potential resource leak" warning is not correct.
no warning:
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
String apiUrl = ...;
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
HttpEntity entity;
try {
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
logger.warn("invoke failed, response status={},key={}",statusCode,key);
httpPost.close();
if (response != null) {
response.close();
}
return null;
}
}
warning:potential resource leak: "response may not be closed at this location"
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
String apiUrl = ...;
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
HttpEntity entity;
try {
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
logger.warn("invoke failed, response status={},key={}",statusCode,key);
closeBoth(httpClient, response)
return null;
}
}
private void closeBoth(CloseableHttpClient client, CloseableHttpResponse resp) {
org.apache.poi.util.IOUtils.closeQuitely(client);
org.apache.poi.util.IOUtils.closeQuitely(resp);
}
why the second approach cause warning?
Thanks!
The Eclipse close warning code only looks at the current method. It does not analyze the closeBoth method to see what it does (and in this case it would also have to look at closeQuitely as well).
Related
I have a method named getResponse() in my program:
public ClosableHTTPResponse getResponse()
{
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(120 * 1000).build();
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
HttpGet httpPostRequest = new HttpGet(getURL);
httpPostRequest.addHeader("Authorization", "Token " + APIKey);
httpPostRequest.setHeader("Content-type", "application/json");
response = httpClient.execute(httpPostRequest);
String statusLine = response.getStatusLine().toString();
System.out.println("Status Line Response: " + statusLine);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) response.close();
if (httpClient != null) httpClient.close();
}
return response;
}
}
When I call this method from external method in the following code:
public void analzyeReponseA()
{
CloseableHttpResponse response = null;
try {
response = getResponse("p1", "p2");
String OKResponse = "HTTP/1.1 200 OK";
String statusLine = response.getStatusLine().toString();
if (statusLine.contains(OKResponse)) {
HttpEntity entity = response.getEntity();
// java.net.SocketException: Socket is closed exception thrown on next line..
String responseString = EntityUtils.toString(entity, "UTF-8");
System.out.println("Response String:\n" + responseString);
}
}
I'm getting a java.net.SocketException: Socket is closed exception
on this line:
String responseString = EntityUtils.toString(entity, "UTF-8");
Based on this and this thread, presumably this is happening bec I call if (response != null) response.close(); in getResponse() method (correct?)
If so, my question now is how do I return a CloseableHttpResponse without the program throwing above exception? Is the only option to call String responseString = EntityUtils.toString(entity, "UTF-8"); in getReponse() method and return a responseString instead of CloseableHttpResponse? What if I still want to access the response object in caller code (like to check status line or something else)?
If I understood the question correctly, I'd first look to see if the code really needed to return an HttpResponse. If the method(s) that call getResponse() all only need, e.g, the contents, then return the contents rather than the response.
Otherwise, you should be able to do, using the try-with-resources approach:
public void callingMethod() {
try (CloseableHttpResponse resp = getResponse();) {
{
// example
HttpEntity entity = resp.getEntity();
}
}
And remove the close from the getResponse() method.
Also, you do not want to be opening/closing the HttpClient on each invocation. That class is designed to be used multiple times. There is more information at You're Using HttpClient wrong and it is destabilizing your software. Thus, you may wish to refactor the code to move the HttpClient elsewhere.
HttpPost showing the file upload status, I want to make progressbar. How can I do.
thanks
public void post(String url, File sendFile) throws UnsupportedEncodingException, IOException {
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient client = new DefaultHttpClient(params);
HttpPost post = new HttpPost(url);
MultipartEntity multiEntity = new MultipartEntity();
multiEntity.addPart("userfile", new FileBody(sendFile));
post.setEntity(multiEntity);
HttpResponse response = client.execute(post);
if (response != null) {
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
}
Not sure if apache httpclient has a ready-made solution for this but you could use an InputStreamBody (instead of FileBody) and wrap the FileInputStream in something that counts how much is already read. Compare this to the size of the file to see how far along you are.
I use this httpclient to post a image to my grails as follows. How do I receive the file in grails?
public static String webPost(String method, File data, Context c) throws Exception {
String json = "";
if (isOnline(c) == true) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
HttpPost httppost ;
try {
httppost = new HttpPost(method);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart("image", new FileBody(data));
httppost.setEntity(entity);
response = httpclient.execute(httppost);
if (response != null) {
HttpEntity r_entity = response.getEntity();
json = EntityUtils.toString(r_entity);
Log.i("ja", json);
}
} catch (Exception e) {
throw new RuntimeException(e.getLocalizedMessage());
} finally {
httpclient = null;
response = null;
httpclient = null;
}
} else {
throw new RuntimeException("No internet connection");
}
return json;
}
My grails:
def image = request.getFile('image')
image.transferTo(new File('c:/p.png') )
Error:
groovy.lang.MissingMethodException: No signature of method: org.apache.catalina.core.ApplicationHttpRequest.getFile() is applicable for argument types: (java.lang.String) values: [image]
Possible solutions: getXML(), getAt(java.lang.String), getAt(java.lang.String), getLocale(), getInfo(), recycle()
at mclient.TestController$_closure1.doCall(TestController.groovy:10)
at mclient.TestController$_closure1.doCall(TestController.groovy)
at java.lang.Thread.run(Thread.java:662)
I'm trying to Get Request with code below but the stringbuilder is always null. The url is correct...
http://pastebin.com/mASvGmkq
EDIT
public static StringBuilder sendHttpGet(String url) {
HttpClient http = new DefaultHttpClient();
StringBuilder buffer = null;
try {
HttpGet get = new HttpGet(url);
HttpResponse resp = http.execute(get);
buffer = inputStreamToString(resp.getEntity().getContent());
}
catch(Exception e) {
debug("ERRO EM GET HTTP URL:\n" + url + "\n" + e);
return null;
}
debug("GET HTTP URL OK:\n" + buffer);
return buffer;
}
I usually do it like this:
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
output = EntityUtils.toString(httpEntity);
}
where output is a String-object.
I am creating a httpClient and I want to add certain header to my HttpGet request
My current code produces the following request.
GET /folder/index.html HTTP/1.0
Host: localhost:4444
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.2.1 (java 1.5)
What I want is to add another header (If-Modified-Since) in that request .
How can I do it?
Thank you :)
public String httpGet(String s) {
String url = s;
StringBuilder body = new StringBuilder();
httpclient = new DefaultHttpClient(); // create new httpClient
HttpGet httpGet = new HttpGet(url); // create new httpGet object
try {
response = httpclient.execute(httpGet); // execute httpGet
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
// System.out.println(statusLine);
body.append(statusLine + "\n");
HttpEntity e = response.getEntity();
String entity = EntityUtils.toString(e);
body.append(entity);
} else {
body.append(statusLine + "\n");
// System.out.println(statusLine);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpGet.releaseConnection(); // stop connection
}
return body.toString(); // return the String
}
Use the setHeader() method on the HttpGet object like follows.
httpGet.setHeader("If-Modified-Since","11/26/2012");
I used this JavaDoc as a reference.
Use the setHeader() method on the HttpGet object like follows for the first one
httpGet.setHeader("If-Modified-Since","11/26/2012");
and then use addHeader() method on the HttpGet object like as follows for the second header.
httpGet.addHeader("If-Expires-On","11/26/2014");