receiving binary data with post made by and Apache HttpClient and MultipartEntity - java

Server receives some data from the client in the post request.
to send that data, I use smth like this:
HttpPost post = new HttpPost(_config.url);
MultipartEntity entity = new MultipartEntity();
for (Entry<String, ContentBody> e : params.entrySet()) {
entity.addPart(e.getKey(), e.getValue());
}
post.setEntity(entity);
When server accept request, data stored in request body. If I read it as char array and convert it ot string, I can see this info:
--ltiKmQX6YRvytGyyKS_F3Zz__tVbvbQktQV
Content-Disposition: form-data; name="file"; filename="art21.jpg.0"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
ÿØÿàJFIFHHÿÛC
2!!22222222222222222222222222222222222222222222222222ÿOX"ÿÄ
However as you can see request contains several parameters: filename and file.
How can I get those parameters from the request body ?

finally found solution:
To get data binary data from post body i use ServletFileUpload from apache:
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

Related

Setting the Content-Transfer-Encoding of upload file in multi-part HTTP request part with Apache HttpClient

I am using apache http library to build and send a multi-part http request that has a file part in the body. Here is a little sample of my request
Request POST HTTPS://hostname:9443/di/resources/upload?logonId=user1 HTTP/1.1:
Headers: Content-Type: multipart/form-data Set-Cookie: Path=/; HttpOnly TrustToken: -1000%2CCaKOjiTFmje3%2Fw0GGcw5%2BDwgxXHjHdQShQgW1QGiHYk%3D
Body: --ncFZGuKp50zCWWImlBFZjxbanSSoJt
Content-Disposition: form-data; name="File 1"; filename="SampleData_en.csv"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Identifier,title,,,,,,,,,,,,,,
Plan: Entries (1) or ent2 (2) ,2,"Set to 1 to specify plan is for Catalog Entries, set to 2 etc .....
--ncFZGuKp50zCWWImlBFZjxbanSSoJt--
The project is that the service is based on apache wink that has a problem decoding the headers in the body which gives this kind of error
Caused by: java.lang.StringIndexOutOfBoundsException
at java.lang.String.substring(String.java:1240)
at org.apache.wink.common.internal.providers.multipart.MultiPartParser.parseHeaders(MultiPartParser.java:264)
at org.apache.wink.common.internal.providers.multipart.MultiPartParser.nextPart(MultiPartParser.java:109)
at org.apache.wink.common.model.multipart.InMultiPart.hasNext(InMultiPart.java:83)
I believe the fix would be to remove the Content-Transfer-Encoding from the body? or change it to maybe a different encoding, maybe base64.
The only problem is that I dont know how to do this using the apache library and haven't been able to find anything examples. Here is the code I am using apache to create the entity portion of my HttpPost request:
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
File file1 = RequestUtils.getFileBody(filePath);
FileBody fileBodyFile1 = new FileBody(file1, org.apache.http.entity.ContentType.create("application/octet-stream"),
file1 .getName());
reqEntity.addPart("File 1", fileBodyFile1);

File gets corrupted while upload [duplicate]

This question already has answers here:
How can I upload files to a server using JSP/Servlet?
(14 answers)
Closed 6 years ago.
I am uploading a file through multipartEntityBuilder in java.
file get uploaded but gets corrupted, as content header gets mixed with data at file.
getting error in text and image formats working fine for pdf.
HttpClient httpclient =new HttpClient();
HttpPut post = new HttpPut(uploadfileurl);
File file = new File(fileUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, "test.txt");
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
HttpEntity entity = builder.build();
post.setEntity(entity);
post.setHeader("enctype", "multipart/form-data");
HttpResponse httpresponse = httpclient.execute(post);
HttpEntity resEntity = httpresponse.getEntity();
Error in file ::
this should be like this :
this file is for testing
but it going like this :
---------------1427465571114
Content-Disposition: form-data; name="upfile"; filename=""
Content-Type: application/octet-stream
this file is for testing
---------------1427465571114--
well, actually it's not corrupted. That is the right http post request.
if you want to get the content of the file, have you tried this method
httpresponse.getEntity().getContent()
it will return InputStream object in which you can try to read the content.
(BTW i am using Zip4J if anyone wonders about my zip.getFile() calls)
As the name suggests : It's to pass a multipart requests.
Here is a snippet of a code to build a multipart header for 2 files :
MultipartEntityBuilder mpeBuilder = MultipartEntityBuilder.create();
mpeBuilder.addBinaryBody(zip.getFile().getName(), zip.getFile());
mpeBuilder.addBinaryBody(zip.getFile().getName(), zip.getFile());
post.setEntity(mpeBuilder.build());
I can then find a file with the following content on my server :
--d_sc7jYe4LHAMikc1LbDw59Yz3pz_bn
Content-Disposition: form-data; name="temp.zip"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
BINARY GARBAGE
--d_sc7jYe4LHAMikc1LbDw59Yz3pz_bn
Content-Disposition: form-data; name="temp.zip"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
BINARY GARBAGE
--d_sc7jYe4LHAMikc1LbDw59Yz3pz_bn--
As you can imagine these headers and separators are here in order to separate and identify the data.
So, I would say this is not garbage, you need to handle this on server side, if you want, say, to have the 2 files saved in the right way.
If you just want to upload a file, there is, as the documentation suggests a fileEntity :
post.setEntity(new FileEntity(zip.getFile()));
By using this entity my zip file is sent to the server without any "corruption"
https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

Multipart JSON POST request

please read my post:
I need to post the image to the JSON WS with this parameters:
Content-Type: multipart/related; boundary="foo_bar_baz"
Content-Length: {number_of_bytes_in_entire_request_body} -- Check your rest client API's. Some would automatically determine content-length at runtime. Eg. jersey client api.
--foo_bar_baz
Content-Type: application/json;
{
"filename": "cloudx.jpg"
}
--foo_bar_baz
Content-Type: image/jpeg
{JPEG data}
--foo_bar_baz--
I'm building Android application and I need to write the request to send the image to the above WS. I was looking around for some time and I didn't found good resource to study this issue I have.
following may give you basic idea
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(<URI>);
HttpEntity entity = new FileEntity(file,ContentType.MULTIPART_FORM_DATA);
//there are other types of entities and content types too check documentation
req.setEntity(entity);
HttpResponse response = httpClient.execute(req);

file size increased during upload

I am uploading file using httpclient. After uploading file size get changed. During file upload some extra things get added in to file.
Before uploading file it contains:
hi this is vipin check
After uploading the file contains:
--j9q7PmvnWSP9wKHHp2w_KCI4Q2jCniJvPbrE0
Content-Disposition: form-data; name="vipin.txt"; filename="vipin.txt"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
hi this is vipin check
--j9q7PmvnWSP9wKHHp2w_KCI4Q2jCniJvPbrE0--
Why file size is changing?
Why does this extra contents get added?
My httpclient code is:
HttpPut httppost = new HttpPut(URIUtil.encodeQuery(newUrl));
httppost.setHeader("X-Auth-Token", cred.getAuthToken());
httppost.addHeader("User-Agent", "NetMagic-file-upload");
System.out.println("Dest : " + dest.getAbsolutePath());
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = (ContentBody) new FileBody(src);
mpEntity.addPart(dest.getName(), cbFile);
httppost.setEntity(mpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
You're doing a PUT request, yet your client uses multipart encoding as commonly uses in HTML form posts.
What appears to be happening is that the client is sending the file to be uploaded as multipart entity, but the server is treating it as an plain file. It is not entirely clear where the fault lies.
It is possible that the server is ignoring the content type in the request header. That would most likely be a bug in the servlet (or whatever) that is responsible for handing the upload request.
It is possible that the client is not setting a content type in the request header. I'd have expected that the client library would take care of that for you. But it is possible that you need to do it explicitly.
I'd advise looking at the request headers as they are sent by the client or received by the server to see if there is a proper multi-part content-type. That will help you determine where the problem is.
But there is an obvious solution. If the server cannot cope with multiparts, change the client side to not send them.

REST - HTTP Post Multipart with JSON

I need to receive an HTTP Post Multipart which contains only 2 parameters:
A JSON string
A binary file
Which is the correct way to set the body?
I'm going to test the HTTP call using Chrome REST console, so I'm wondering if the correct solution is to set a "label" key for the JSON parameter and the binary file.
On the server side I'm using Resteasy 2.x, and I'm going to read the Multipart body like this:
#POST
#Consumes("multipart/form-data")
public String postWithPhoto(MultipartFormDataInput multiPart) {
Map <String, List<InputPart>> params = multiPart.getFormDataMap();
String myJson = params.get("myJsonName").get(0).getBodyAsString();
InputPart imagePart = params.get("photo").get(0);
//do whatever I need to do with my json and my photo
}
Is this the way to go?
Is it correct to retrieve my JSON string using the key "myJsonName" that identify that particular content-disposition?
Are there any other way to receive these 2 content in one HTTP multipart request?
If I understand you correctly, you want to compose a multipart request manually from an HTTP/REST console. The multipart format is simple; a brief introduction can be found in the HTML 4.01 spec. You need to come up with a boundary, which is a string not found in the content, let’s say HereGoes. You set request header Content-Type: multipart/form-data; boundary=HereGoes. Then this should be a valid request body:
--HereGoes
Content-Disposition: form-data; name="myJsonString"
Content-Type: application/json
{"foo": "bar"}
--HereGoes
Content-Disposition: form-data; name="photo"
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
<...JPEG content in base64...>
--HereGoes--

Categories