I have some Java code that I 'inherited' from a previous co-worker. Part of it connects to an outside URL using method GET and retrieves a small amount of XML for parsing. We've been having issues recently with this connection crashing our website due to the vendor website hanging and using up resources on our side. One issue is due to no timeouts being set when our code uses the HttpGet object. Is there a way to fine-tune timeouts using this object, or is there a better way to pull back this XML?
Would I be better off using another API?
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param1","foobar"));
URI uri = URIUtils.createURI("http", "myhost.com", -1, "mypath",
URLEncodedUtils.format(params, "UTF-8"), null);
// there is no timeout here??
HttpGet httpGet = new HttpGet(uri);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpGet);
String result = IOUtils.toString(httpResponse.getEntity()
.getContent(), "UTF-8");
Thanks!
try this instead
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param1","foobar"));
URI uri = URIUtils.createURI("http", "myhost.com", -1, "mypath",
URLEncodedUtils.format(params, "UTF-8"), null);
HttpGet httpGet = new HttpGet(uri);
HttpClient httpClient = new DefaultHttpClient();
// set the connection timeout value to 30 seconds (30000 milliseconds)
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
httpClient = new DefaultHttpClient(httpParams);
HttpResponse httpResponse = httpClient.execute(httpGet);
String result = IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8");
From Java HTTP Client Request with defined timeout
Related
I need to post some form parameters to a server through an HTTP request (one of which is a file). So I use Apache HTTP Client like so...
HttpPost httpPost = new HttpPost(urlStr);
params = []
params.add(new BasicNameValuePair("username", "bond"));
params.add(new BasicNameValuePair("password", "vesper"));
params.add(new BasicNameValuePair("file", payload));
httpPost.setEntity(new UrlEncodedFormEntity(params));
httpPost.setHeader("Content-type", "multipart/form-data");
CloseableHttpResponse response = httpclient.execute(httpPost);
The server returns an error, stack trace is..
the request was rejected because no multipart boundary was found
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:954)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
I understand from other posts that I need to somehow come up with a boundary, which is a string not found in the content. But how do I create this boundary in the code I have above? Should it be another parameter? Just a code sample is what I need.
As the exception says, you have not specified the "multipart boundary". This is a string that acts as a separator between the different parts in the request. But in you case it seems like you do not handle any different parts.
What you probably want to use is MultipartEntityBuilder so you don't have to worry about how it all works under the hood.
It should be Ok to do the following
HttpPost httpPost = new HttpPost(urlStr);
File payload = new File("/Users/CasinoRoyaleBank");
HttpEntity entity = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addBinaryBody("file", payload)
.addTextBody("username", "bond")
.addTextBody("password", "vesper")
.build();
httpPost.setEntity(entity);
However, here is a version that should be compatible with #AbuMariam findings below but without the use of deprecated methods/constructors.
File payload = new File("/Users/CasinoRoyaleBank");
ContentType plainAsciiContentType = ContentType.create("text/plain", Consts.ASCII);
HttpEntity entity = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addPart("file", new FileBody(payload))
.addPart("username", new StringBody("bond", plainAsciiContentType))
.addPart("password", new StringBody("vesper", plainAsciiContentType))
.build();
httpPost.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httpPost);
The UrlEncodedFormEntity is normally not used for multipart, and it defaults to content-type application/x-www-form-urlencoded
I accepted gustf's answer because it got rid of the exception I was having and so I thought I was on the right track, but it was not complete. The below is what I did to finally get it to work...
File payload = new File("/Users/CasinoRoyaleBank")
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
entity.addPart( "file", new FileBody(payload))
entity.addPart( "username", new StringBody("bond"))
entity.addPart( "password", new StringBody("vesper"))
httpPost.setEntity( entity );
CloseableHttpResponse response = httpclient.execute(httpPost);
I'm working on simple client server communication using HttpPost. From the client side I'm setting a parameter(filename).
At the server side when I try to get the parameter value it's always showing null. I tried using MultiPartEntity but even that is not working.
Below is my client code:
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx:yyyy");
InputStreamEntity reqEntity = new InputStreamEntity(
new FileInputStream(dataFile), -1);
reqEntity.setContentType("binary/octet-stream");
// Send in multiple parts if needed
reqEntity.setChunked(true);
httppost.setEntity(reqEntity);
//setting the parameter
httppost.getParams().setParameter("filename", "xxxx.xml");
HttpResponse response = httpclient.execute(httppost);
int respcode = response.getStatusLine().getStatusCode();
And this is my servlet code:
response.setContentType("binary/octet-stream");
Scanner scanner = new Scanner(request.getInputStream());
// reading the parameter
String filename = request.getParameter("filename");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\" + filename)));
Kindly let me know any possible solution for this issue.
Thanks in advance!
Ur setting parameters wrong... at the client side, do this:
ArrayList<NameValuePair> postParameters = postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("filename", "xxxx.xml");
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
HttpResponse response = httpclient.execute(httppost);
i do multiple request to the same url using httpclient.execute(request).
Can I re-use the connection for the consecutive requests?
how can i optimise the code without declaring HttpClient again and again.
for(int i=0;i<=50;i++)
{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("my_url");
HttpResponse response = client.execute(request);
System.out.println(response.getStatusLine().getStatusCode());
}
In order to use a single client in your code (based on Exception using HttpRequest.execute(): Invalid use of SingleClientConnManager: connection still allocated and Lars Vogel Apache HttpClient - Tutorial):
Step 1. Move the client generation outside the for-loop.
Step 2. You should read the response content and close the stream. If you don't do this you will get the following exception
Exception in thread "main" java.lang.IllegalStateException:
Invalid use of SingleClientConnManager: connection still allocated.
In code:
//step 1
HttpClient client = new DefaultHttpClient();
for(int i=0;i<=50;i++) {
HttpGet request = new HttpGet("my_url");
HttpResponse response = client.execute(request);
System.out.println(response.getStatusLine().getStatusCode());
//step 2
BufferedReader br = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
//since you won't use the response content, just close the stream
br.close();
}
try below.
HttpUriRequest httpGet = new HttpGet(uri);
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
Hi I am trying to make 2 GET requests to a single connection. ie
HttpGet get1 = new HttpGet("http://www.google.com/search?q=HelloWorld");
HttpGet get2 = new HttpGet("http://www.google.com/search?q=SecondSearch");
HttpResponse response = null;
response = client.execute(get1);
response = client.execute(get2);
I would like to get the body from the second execution. Obviously this fails, because it says you must release the connection first. I need to maintain the exact session - for instance, if I navigate to a site where the first step is to login, I need to navigate to any subsequent pages with the same cookie.
It's probably something incredibly simple that I am doing wrong!
You need to use a CookieStore
CookieStore cookieStore = new BasicCookieStore();
DefaultHttpClient client1 = new DefaultHttpClient();
client1.setCookieStore(cookieStore);
HttpGet httpGet1 = new HttpGet("...");
HttpResponse response1 = client1.execute(httpGet1);
DefaultHttpClient client2 = new DefaultHttpClient();
client2.setCookieStore(cookieStore);
HttpGet httpGet2 = new HttpGet("...");
HttpResponse response2 = client2.execute(httpGet2);
In the above code, both client2 will re-use cookies from the client1 request.
When communicating with http to http://forecast.weather.gov/zipcity.php I need to obtain the URL that is generated from a request.
I have printed out the headers and their values from the http response message but there is no location header. How can I obtain this URL? (I'm using HttpClient)
It should be similar to:
HttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
HttpClientParams.setRedirecting(params, false);
HttpGet method = new HttpGet("http://forecast.weather.gov/zipcity.php?inputstring=90210");
HttpResponse resp = client.execute(method);
String location = resp.getLastHeader("Location").getValue();
EDIT: I had to make a couple minor tweaks, but I tested and the above works.