I am developing a web application with struts2&spring3 and one of the last things I need to do is the communication between my server and another server where I have to send a XML file and after wait for its response.
As someone said me, I have implemented the sending of the XML file by HTTP with the library HttpClient4 (from Apache):
File file = new File(fileName);
FileEntity entity = new FileEntity(file, "text/xml; charset=\"UTF-8\"");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost method = new HttpPost(server);
method.setEntity(entity);
HttpResponse response = httpclient.execute(method);
But now I have to implement the waiting and getting of the response that the other server will send me. The problem is that the other server is still not developed, so, which way you think it would be the best to get that answer? by HTTP also would be perfect but I don't know which library and how to do it.
Thank you very much in advance for all your help,
Aleix
Here I find two options
Send response immediately.
Develop a module [client side] which accepts response from server after request is received and added to queue [ Asynchronous mode ]
Related
I do have the following scenario:
1) The Client sends a HTTP request with an enclosing entity to a Server, via a socket.
2) The Server uploads the enclosing entity to another location, let's call it Storage.
I am required to implement only the Server.
So far, I was able to implement it using Apache HTTP Components library using something like:
// The request from the client
org.apache.http.HttpRequest request = ...;
// The org.apache.http.entity.InputStreamEntity will
// read bytes from the socket and write to the Storage
HttpEntity entity = new InputStreamEntity(...)
BasicHttpEntityEnclosingRequest requestToStorage = new ......
requestToStorage.setEntity(entity);
CloseableHttpClient httpClient = ...
CloseableHttpResponse response = httpClient.execute(target, requestToStorage );
So far so good. Problem is, the Storage server requires authentication. When the Server makes the first request (via Apache Http Client API), the Storage responds with 407 Authentication Required. The Apache Http Client makes the initial handshake then resends the request, but now there is no entity since it has already been consumed for the first request.
One solution is to cache the entity from the Client, but it can be very big, over 1 GB.
Question Is there a better solution, like pre-sending only the request's headers?
Use the expect-continue handshake.
CloseableHttpClient client = HttpClients.custom()
.setDefaultRequestConfig(
RequestConfig.custom()
.setExpectContinueEnabled(true)
.build())
.build();
I have a REST Service on https connection that accepts file upload as multipart (i.e. metadata of the file and file itself)
How can I use Jersey (for websphere) or HttpClient to call REST service and send file as multipart. I want send file as multiple streams of different sizes because we can have file more than 1GB. Moreover, the REST service is using Windows NT authentication for authorization and is on https.
Can anyone give example how I can achieve this? I have used multipart httpClient. Sending it as a stream does not work. Below is my code using httpClient 4.5.2
====================================
InputStream stream = new FileInputStream("test.doc");
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setStrictMode();
InputStreamBody streamBody = new InputStreamBody(stream, docHandler.getFilename());
FormBodyPart filePart = FormBodyPartBuilder.create()
.setName("Binary")
.addField(Constants.RETRIEVAL_NAME_FIELD, "test.doc")
.addField("Content-Type",docHandler.getContentType())
.setBody(streamBody)
.build();
entityBuilder.addPart(filePart);
HttpPost httpPostRequest = new HttpPost();
httpPostRequest.setEntity(entityBuilder.build());
httpClient.execute(httpPostRequest);
====================================
But when I execute this code, I am getting following error
org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity
Any idea why I am getting this error. If I convert stream to byte array and use ByteArrayBody instead, then it works fine but I noticed in Fiddler that three request calls are being made to the server and in every call the entire content of the file is being copied. So, if my file is of 1GB then entire content will be sent to the server three times.
Firstly, how can I achieve sending large file in chunks or multiple streams so that entire file is not sent in one call. Secondly, is there a way to avoid having 3 calls to the server for NTLM authentication?
Any pointers?
Cheers!
The Exception occurs because InputStreamBody is not repeatable (especially for large streams). A general InputStream can be read from only once.
FileBody is repeatable, as a File can be read from multiple times.
One reason for the repeatable reads may be the (NTLM)authorisation(did not check this).
You may avoid this by doing the first two NTML authorisation steps before the actual request and setting/sending the
Authorization: NTLM <base64-encoded type-3-message> header, but that does not solve the problem, because the network may not be reliable enough and you have to retry anyway.
You basically have two options:
use repeatable ContentBody implementations only like FileBody or own repeatable ContentBody instance.
make sure the request does not need to be retried.
Please note the latter is not always possible. As mentioned before request retries due to authentication failures can be avoided, but those due to I/O errors cannot.
I have a strange problem I have been trying to solve for the last two days, and seem to have narrowed it down to the cookies attached to the global DefaultHttpClient variable associated with my application.
When I use the client with post params, everything hangs after the first time it is used. I don't get any requests to my server, the application just refuses to do anything. If there are no post parameters, everything works just fine. Here is the applicable code.
httppost.setEntity(new UrlEncodedFormEntity(pairs,"UTF-8"));
DefaultHttpClient defhttpClient = new DefaultHttpClient();
logger.info("URL Encoded");
//When I pass the cookies things stop working...
//defhttpClient.setCookieStore(httpclient.get_cookies());
response = defhttpClient.execute(httppost);
logger.info("Received response");
If I make a new DefaultHttpClient and run the post request with parameters, the client can talk to the server just fine. The only problem is that I need the cookies from the old client to tell the server who the current user is. When I take the cookies from my old client and give them to my new one, the application hangs. Again, I dont even see a request coming into my server.
Does anyone have any idea what's going on here?
Alright, so I couldn't figure out how to do this by sending the message in the body with setentity. Just decided to put the json data in the header instead and everything seems to work fine. Not really too big of a problem. Would have preferred to do it the right way, but sometimes you can't get everything you want. Here is the code for anyone with the same problem.
JSONObject post_params = new JSONObject();
for(NameValuePair pair : pairs){
post_params.put(pair.getName(), pair.getValue());
}
httppost.setHeader("json",post_params.toString());
response = httpclient.get_client().execute(httppost);
i am creating a desktop application which send file to an tomcat server. the servlet receiver and saves file fine.
I need some help to do a java program that post in a https site. I dont know how to put the parameters because it a multpart form data contect type.. Please help! when I do a post with firefox its like this...
This will depend. I've used the following technique to upload a multi-part file to a server before, based on providing a series of form key/name pairs.
This will be depended on you own requirements and what the servlet is actually expecting...
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
String name = file.getName();
entity.addPart(new FormBodyPart("someFormParameter", new StringBody("someFormName")));
/*...*/
entity.addPart("formFileNameParameter", new FileBody(file, mimeType));
HttpClient client = /*...*/
HttpPost post = new HttpPost(url.toURI());
post.setEntity(entity);
HttpResponse response = client.execute(post);
// Process response
I have two web applications in two different server.I want send some data in header or request to other web application.How can I do that, please help me.
You can pass data by many means:
by making http request from your app:
URLConnection conn = new URL("your other web app servlet url").openConnection();
// pass data using conn. Then on other side you can have a servlet that will receive these calls.
By using JMS for asynchronous communication.
By using webservice (SOAP or REST)
By using RMI
By sharing database between the apps. So one writes to a table and the other reads from that table
By sharing file system file(s)...one writes to a file the other reads from a file.
You can use socket connection.
HttpClient can help
http://hc.apache.org/index.html
Apache HttpComponents
The Apache HttpComponents™ project is responsible for creating and
maintaining a toolset of low level Java components focused on HTTP and
associated protocols.
One web application is functioning as the client of the other. You can use the org.apache.http library to create your HTTP client code in Java. How you will do this depends on a couple of things:
Are you using http or https?
Does the application you are sending data to have a REST API?
Do you have a SOAP based web service?
If you have a SOAP based web service, then creating a Java client for it is very easy. If not, you could do something like this and test the code in a regular Java client before trying to run it in the web application.
import org.apache.http.client.utils.*;
import org.apache.http.*;
import org.apache.http.impl.client.*;
HttpClient httpclient = new DefaultHttpClient();
try {
URIBuilder builder = new URIBuilder();
builder.setHost("yoursite.com").setPath(/appath/rsc/);
builder.addParameter("user", username);
builder.addParameter("param1", "SomeData-sentAsParameter");
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.getStatusLine().toString());
if (response.getStatusLine().getStatusCode() == 200) {
String responseText = EntityUtils.toString(response.getEntity());
httpclient.getConnectionManager().shutdown();
} else {
log(Level.SEVERE, "Server returned HTTP code "
+ response.getStatusLine().getStatusCode());
}
} catch (java.net.URISyntaxException bad) {
System.out.println("URI construction error: " + bad.toString());
}