I have a httpClient function which returns an HttpResponse object to the calling function.
public HttpResponse postRequest(String uri, String body) throws IOException {
HttpResponse response;
String url = baseUrl + uri;
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.build()) {
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(body));
post.setHeader(AUTHORIZATION_HEADER, authorization);
post.setHeader(CONTENTTYPE_HEADER, APPLICATION_JSON);
post.setHeader(ACCEPT_HEADER, APPLICATION_JSON);
response = httpClient.execute(post);
} catch (IOException e) {
System.out.println("Caught an exception" + e.getMessage().toString());
logger.error("Caught an exception" + e.getMessage().toString());
throw e;
}
return response;
}
In my calling function I call, HttpResponse response = httpRequest.postRequest(url,body); (where httpRequest is an object for the class which contains the function
When I try to parse the contents of the received the response through
String responseString = IOUtils.toString(response.getEntity()
.getContent(), "UTF-8");
I get an error Socket is closed.
How do I use the contents of HttpResponse once the connection is closed?
Your try-with-resources statement is closing the entire client. You don't want that. Remove it. You want the close to happen when the caller closes the response you're returning.
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.
I am sending NameValuePair parameters to a php file on my server and this php file echoes one of three string values.
I need to write code in Java to send these parameters to the PHP file via POST and also save the php file's echo response to a String.
This is what I have so far:
public String getStringFromUrl(String url, List<NameValuePair> params) throws IOException {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
HttpPost httpPost = new HttpPost(url);
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
String response2 = (String) response;
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return response;
}
I know I have the right lines of code for sending the POST parameters but how do I read the value the php file echoes corresponding to the given POST parameters?
You can read the post response this way:
HttpResponse response = client.execute(post);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
See the full example here:
http://www.mkyong.com/java/apache-httpclient-examples/
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");
I have a code like this:
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(server);
try {
JSONObject params = new JSONObject();
params.put("email", email);
StringEntity entity = new StringEntity(params.toString(), "UTF-8");
httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
httpPost.setEntity(entity);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(httpPost, responseHandler);
JSONObject response = new JSONObject(responseBody);
fetchUserData(response);
saveUserInfo();
return true;
} catch (ClientProtocolException e) {
Log.d("Client protocol exception", e.toString());
return false;
} catch (IOException e) {
Log.d`enter code here`("IOEXception", e.toString());
return false;
} catch (JSONException e) {
Log.d("JSON exception", e.toString());
return false;
}
And i want to have a response even if I have HTTP 403 Forbidden to get error message
The BasicResponseHandler only returns your data if a success code (2xx) was returned. However, you can very easily write your own ResponseHandler to always return the body of the response as a String, e.g.
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
#Override
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
return EntityUtils.toString(response.getEntity());
}
};
Alternatively, you can use the other overloaded execute method on HttpClient which does not require a ResponseHandler and returns you the HttpResponse directly. Then call EntityUtils.toString(response.getEntity()) in the same way.
To get the status code of a response, you can use HttpResponse.getStatusLine().getStatusCode() and compare to to one of the static ints in the HttpStatus class. E.g. code '403' is HttpStatus.SC_FORBIDDEN. You can take particular actions as relevant to your application depending on the status code returned.
According to the documentation for BasicResponseHandler:
If the response was unsuccessful (>= 300 status code), throws an HttpResponseException.
You could catch this type of exception (Note: you are already catching the supertype of this exception ClientProtocolException) and you could put some custom logic in that catch block to create / save some response when you encounter an error situation, such as the 403.