public static String sendRequest(UUICRequest requset) throws
ClientProtocolException, IOException
{
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10 * 1000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
HttpGet httpGet = new HttpGet(requset.toUrl());
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
response.close();
httpClient.close();
return EntityUtils.toString(entity, "UTF-8");
}
It throws java.net.SocketException: socket closed.
I debugged and ran this program line by line, just found entity changed when excuted:
response.close();
httpClient.close();
So I rewrite my code:
public static String sendRequest(UUICRequest requset) throws
ClientProtocolException, IOException
{
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10 * 1000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
HttpGet httpGet = new HttpGet(requset.toUrl());
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
String ret = EntityUtils.toString(entity, "UTF-8");//+
response.close();
httpClient.close();
return ret;//M
}
This code works as expected and successfully ends.
My question is, why httpclient will reset entity after closing response and httpClient?
My question is, why httpclient will reset entity after closing response and httpClient?
Streaming HTTP entities (such as those returned with an HttpResponse) are attached to the underlying connection in order to be able to stream data out without any intermediate buffering. Closing HttpResponse before response content has been fully consumed causes the underlying connection to get reset.
Related
I have some code as follow:
public class HttpUtil {
public static String sendGetRequest(String url) {
String result = null;
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
HttpGet httpget = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
I want to know the connection is long connection as using keepalive in HTTP 1.1 when I using sendGetRequest. I want to use long connection in java.
Default Connection keep alive strategy is keep alive indefinitely
If the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely.
To customize CloseableHttpClient's keep-alive strategy use setKeepAliveStrategy:
CloseableHttpClient client = HttpClients.custom()
.setKeepAliveStrategy(myStrategy)
.build();
I am just trying to call an external web-service from my Java AWS Lambda function. To do this I can't get the org.apache.http client to work. I have the code:
public static String get(String get) throws ClientProtocolException, IOException{
RequestConfig defaultRequestConfig = RequestConfig.custom().setExpectContinueEnabled(true).build();
HttpGet httpGetRequest = new HttpGet(get);
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig).setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
httpGetRequest.setConfig(requestConfig);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse httpResponse = httpClient.execute(httpGetRequest); <<<<<
HttpEntity entity = httpResponse.getEntity();
StringBuffer all = new StringBuffer();
if (entity != null) {
InputStream inputStream = entity.getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(new BufferedInputStream(inputStream)));
String read;
while ((read = in.readLine()) != null){
all.append(read);
all.append("\n");
}
httpClient.close();
}
return all.toString();
}
Once it is deployed it hangs on the line HttpResponse httpResponse = httpClient.execute(httpGetRequest); <<<<< above.
I can prove that I have connectivity from the lambda function to the internet by setting up a Socket connection e.g. Socket s = new Socket(InetAddress.getByName("bbc.co.uk"), 80); and I can retrieve data this way.
So the question is either what is wrong with the first code fragment which works locally but not when deployed? or is there a preferred way to call web-services from AWS lambda functions in Java (I have had a search but can't find a best practice) ? I would prefer not to have to hand craft the HTTP requests using Sockets if I can help it.
The issue here is the usage of Apache HttpClient which is a large library. Switching to OkHttp fixed the issue in my case.
Please try to use Rest Template to make this call.
try {
String url = "baseurl for AWS insatnce +8080/Testing/mailGenration/generate?msg=20;
logger.log("Building HttpClient......");
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
logger.log("Response Code : " + response.getStatusLine().getStatusCode());
} catch (Exception e) {
logger.log("Exception in sendhttpclient:" + e);
}
I'm writing an Android application. It sends a HTTPPost to a server and receives the answer, when I use :
public final HttpResponse execute (HttpUriRequest request)
it's ok,
but when I try to use:
public T execute (HttpUriRequest request, ResponseHandler<? extends T> responseHandler)
it throws ClientProtocolException
because of some reasons I wanna use the second function, what should I do? What is the exception for ?
here is the code that uses the first function :
HttpPost httppost = new HttpPost("http://foo.Com/GeneralControls/Service.asmx/Login");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost) ;
and here is the code that uses the second function:
HttpPost httppost = new HttpPost("http://foo.Com/GeneralControls/Service.asmx/Login");
DefaultHttpClient httpclient = new DefaultHttpClient();
ResponseHandler<String> responseHandler=new BasicResponseHandler();
String response = httpclient.execute(httppost , responseHandler) ;
throws ClientProtocolException.
See the below code is working fine for me
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE,
Util.cookieStore);
try {
HttpResponse response = httpclient.execute(httppost,
localContext);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But you are trying to pass ResponseHandler and it accepts httpContext
The problem was a protocol problem, the webservice was changing the Destination URL and it produced an Exception
So I'm getting Unauthorized error after authorizing with http client. The website im trying to access has NTLM authentication. If someone could help with this issue it would be appreciated.
public class ClientAuthentication {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("website", 80),
new UsernamePasswordCredentials("username", "password"));
HttpGet httpget = new HttpGet("http://cdg5.intranet.bell.ca/BlackFoot/Ont/");
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
EntityUtils.consume(entity);
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
}
and here is the result im getting
"executing requestGET http://cdg5.intranet.bell.ca/BlackFoot/Ont/
HTTP/1.1
HTTP/1.1 401 Unauthorized Response content length: 1656"
I'm POSTing some data to a server that is answering a 302 Moved Temporarily.
I want HttpClient to follow the redirect and automatically GET the new location, as I believe it's the default behaviour of HttpClient. However, I'm getting an exception and not following the redirect :(
Here's the relevant piece of code, any ideas will be appreciated:
HttpParams httpParams = new BasicHttpParams();
HttpClientParams.setRedirecting(httpParams, true);
SchemeRegistry schemeRegistry = registerFactories();
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(clientConnectionManager, httpParams)
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HTTP.CONTENT_TYPE, contentType);
postRequest.setHeader(ACCEPT, contentType);
if (requestBodyString != null) {
postRequest.setEntity(new StringEntity(requestBodyString));
}
return httpClient.execute(postRequest, responseHandler);
For HttpClient 4.3:
HttpClient instance = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();
For HttpClient 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());
For HttpClient < 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new DefaultRedirectStrategy() {
/** Redirectable methods. */
private String[] REDIRECT_METHODS = new String[] {
HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME
};
#Override
protected boolean isRedirectable(String method) {
for (String m : REDIRECT_METHODS) {
if (m.equalsIgnoreCase(method)) {
return true;
}
}
return false;
}
});
The default behaviour of HttpClient is compliant with the requirements of the HTTP specification (RFC 2616)
10.3.3 302 Found
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
You can override the default behaviour of HttpClient by sub-classing DefaultRedirectStrategy and overriding its #isRedirected() method.
It seem http redirect is disable by default. I try to enable, it work but I'm still got error with my problem. But we still can handle redirection pragmatically. I think your problem can solve:
So old code:
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User-Agent");
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
long contentSize = httpResponse.getEntity().getContentLength();
This code will return contentSize = -1 if http redirect happend
And then I handle redirect by myself after trying enable default follow redirection
AndroidHttpClient client;
HttpGet httpGet;
HttpResponse response;
HttpHeader httpHeader;
private void handleHTTPRedirect(String url) throws IOException {
if (client != null)
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(url));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
while (httpHeader.length > 0) {
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(httpHeader[0].getValue()));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
}
}
In use
handleHTTPRedirect(url);
long contentSize = httpResponse.getEntity().getContentLength();
Thanks
Nguyen
My solution is using HttClient. I had to send the response back to the caller. This is my solution
CloseableHttpClient httpClient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
//this reads the input stream from POST
ServletInputStream str = request.getInputStream();
HttpPost httpPost = new HttpPost(path);
HttpEntity postParams = new InputStreamEntity(str);
httpPost.setEntity(postParams);
HttpResponse httpResponse = null ;
int responseCode = -1 ;
StringBuffer response = new StringBuffer();
try {
httpResponse = httpClient.execute(httpPost);
responseCode = httpResponse.getStatusLine().getStatusCode();
logger.info("POST Response Status:: {} for file {} ", responseCode, request.getQueryString());
//return httpResponse ;
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
logger.info(" Final Complete Response {} " + response.toString());
httpClient.close();
} catch (Exception e) {
logger.error("Exception ", e);
} finally {
IOUtils.closeQuietly(httpClient);
}
// Return the response back to caller
return new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);
For HttpClient v5, just use the below:
httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new DefaultRedirectStrategy() {
#Override
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
throws ProtocolException {
return false;
}
}).build();