Implementing HttpComponent's HttpAsyncClient with Multipart Entity - apache-httpcomponents

I would like some help, clarification on using HttpAsyncClient with multipart entity. Basically I am trying to upload content of a file (byte[]) as a MultiPart Body using HttpAsyncClient.
Sample of how I am using it:
CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.createDefault();
httpAsyncClient.start();
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.addPart("file",new ByteArrayBody(Base64.decodeBase64(fileContent),"");
reqEntity.addPart("fileSize",new StringBody("1234"));
reqEntity.addPart("fileName",new StringBody("xyz.txt"));
reqEntity.addPart("fileType",new StringBody("text/plain"));
reqEntity.addPart("SEQ_NUM",new StringBody("23432"));
HttpPost httppost = new HttpPost(endpointUrl);
httppost.setEntity(reqEntity.build());
Future<HttpResponse> future = httpAsyncClient.execute(httppost, null);
httpAsyncClient.close();
Below are the Pom Dependences added to the project for this implementation:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.6</version>
</dependency>
Now, I am blocked at a place where the following exception is thrown:
java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: Multipart form entity does not implement #getContent()
I have did lot of search over the internet and could find very little details about the new HttpAsyncClient implementation. I found some users been asked similar questions but none of the solution worked for me.
[HttpAsyncClient Multipart Entity not working?]
In the below link a user suggested to wrap the MultipartEntity instance with BufferedHttpEntity. So, I updated the code as below(not sure its correct) but still the same exception.
CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.createDefault();
httpAsyncClient.start();
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.addPart("file",new ByteArrayBody(Base64.decodeBase64(fileContent),"");
reqEntity.addPart("fileSize",new StringBody("1234"));
reqEntity.addPart("fileName",new StringBody("xyz.txt"));
reqEntity.addPart("fileType",new StringBody("text/plain"));
reqEntity.addPart("SEQ_NUM",new StringBody("23432"));
HttpPost httppost = new HttpPost(endpointUrl);
httppost.setEntity(new BufferedHttpEntity(reqEntity.build()));
Future<HttpResponse> future = httpAsyncClient.execute(httppost, null);
httpAsyncClient.close();
I would appreciate your help in identifying the cause.
References:
http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/201311.mbox/%3c13034392.132.1384195516775.JavaMail.Hal#Harold-Rosenbergs-MacBook-Pro.local%3e
http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/201206.mbox/%3C1339240012.2405.12.camel#ubuntu%3E

MultipartFormEntity can not be used asynchronously. One of the options is to write the entity out to ByteArrayOutputStream and create a NByteArrayEntity out of it.
File file = new File(filePath);
ByteArrayBody body;
body = new ByteArrayBody(FileUtils.readFileToByteArray(file), file.getName());
HttpEntity mEntity = MultipartEntityBuilder.create()
.setBoundary("-------------" + boundary)
.addPart("file", body)
.build();
ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
mEntity.writeTo(baoStream);
HttpEntity nByteEntity = new NByteArrayEntity(baoStream.toByteArray(), ContentType.MULTIPART_FORM_DATA);
httppost.setEntity(nByteEntity );

Related

Porting JSONObject (Android) to JObject (JSON.NET)

I have some native android code which receives data back from the server which is then added to a JSONObject for later manipulation.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseStr = new StreamReader(response.GetResponseStream()).ReadToEnd();
JSONObject responseObj = new JSONObject(responseStr);
However, I'm moving this over to an mvvm framework so JSONObject can't be used (I'm also happier working with the much nicer JSON.NET libraries).
I've changed the JSONObject to JObject and come up with the following which compiles, but throws an exception on running (Cannot add a jtoken to a object)
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseStr = new StreamReader(response.GetResponseStream()).ReadToEnd();
var responseObj = new JObject(responseStr);
From what I've read, this should work (but is obviously isn't). Is there a way to store the responseStr as a JObject?
use JObject.Parse
var responseObj = new JObject.Parse(responseStr);

JavaMail requires an InputStreamSource that creates a fresh stream for every call

I'm trying to send an attachment using JavaMail via Spring 2.5's MailSender, but I keep getting this error:
Passed-in Resource contains an open stream: invalid argument.
JavaMail requires an InputStreamSource that creates a fresh stream for every call.
I am using an InputStreamResource :
InputStream crofileInputStream = emailDraft.getAttachmentCroFile().getInputStream();
InputStream nacfileInputStream = emailDraft.getAttachmentNacFile().getInputStream();
InputStream sourcefileInputStream = emailDraft.getAttachmentSourceFile().getInputStream();
InputStreamSource[] attachments = {new InputStreamResource(crofileInputStream),new InputStreamResource(nacfileInputStream),new InputStreamResource(sourcefileInputStream)};
sentEmailLog = mailSenderService.sendMIMEMessage(emailDraft, attachmentFileNames, attachments);
this last instruction calls
MimeMessageHelper.addAttachment(fileName,attachments[i]) for each attachment.
Please how could i solve this issue ?
Thanks for you help.
Try to use javax.mail.util.ByteArrayDataSource
String mailTo = message.getHeaders().get("emailAddress", String.class);
MimeMessage mimeMessage = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
ByteArrayDataSource attachment = new ByteArrayDataSource(message.getPayload(), "application/octet-stream");
helper.addAttachment("document.zip", attachment);
helper.setText("text content of the email");
You could also check this example:
https://www.javatips.net/api/javax.mail.util.bytearraydatasource

How do I replace an existing Community file on IBM SmartCloud

I am trying to replace an existing Community file using the following java
Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("createVersion", "false");
fileEntry = fileService.updateCommunityFile(fis, fileUuid, fileName, communityLibraryId, paramsMap);
But it is returning a HTTP 411:Length required error.
I am using the latest build (1.1.5.20150520-1200.jar)
Does anyone have a suggestion as to what i am missing?
I tried recreating the issue but I am able to upload New version of Community file correctly with and without version, using the updateCommunityFile API. I do not get any Length related error. This is the snippet I am using :
java.io.File file = new java.io.File("C://TestUploadCommunity.txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (Exception e) {
//TODO
}
fileEntry = fileService.updateCommunityFile(fis, fileEntry.getFileId(), fileEntry.getLabel(), communityLibraryId, params);
Can you share more details on your sample, what exactly is your fis?
I have tried this on 2 environments and I do not see any issue.
Also, from the entry you have pasted,
"Request to url apps.na.collabserv.com/files/basic/api/library... /document/... /entry?content-length=6600&createVersion=false returned an error response 411:Length Required HTTP/1.1 411"
It seems that somehow an incorrect content-length is passed for your request.
Can you share the sample that you are using?

Android HttpPost and HttpClient Substitute

Just a quick question.
Until now I have been using HttpClient and HttpPost to post a file and some parameters to a php script on my server.
However they have been deprecated.
I was wondering what i could use to substitute it.
I found some answers on other posts but unfortunately i didn't manage to integrate any of them with the HttpMime Library that i am using for a MultiPartEntity post.
HttpClient httpclient = new DefaultHttpClient(); // Deprecated
HttpPost httpost = new HttpPost(inData[0].URL); // Deprecated
// Request To Entity
MultipartEntity entity = new MultipartEntity();
// Add Parameters
for(Request r : inData[0].Params)
entity.addPart(r.Key, new StringBody(r.Body));
// Add File
entity.addPart("img", new FileBody(inData[0].FileToUpload));
httpost.setEntity(entity);
HttpResponse responsePOST = httpclient.execute(httpost); // Deprecated
HttpEntity resEntity = responsePOST.getEntity(); // Deprecated
if (resEntity != null)
inData[0].RequestResult.add(EntityUtils.toString(resEntity));
else
throw new Exception("");
return inData[0];
} catch (Exception e) {
e.printStackTrace();
inData[0].RequestResult.add("ERROR");
}
return inData[0];
Would anyone point me in the right direction? Thanks
At my job we also used the apache libraries but we have replaced them with okHTTP.
More information about okHTTP can be found here: http://square.github.io/okhttp/
Information about uploading multipart files can be found here:
Uploading a large file in multipart using OkHttp

MultipartEntityBuilder setMode() not working

Using apache httpcomponents-client-4.3.6-bin libs.
This code is producing an HttpEntity intance with both parts containing the Content-Tranfer-Encoding header. I can't eliminate these headers using setMode(HttpMultipartMode.BROWSER_COMPATIBLE) or setLaxMode(). Does anyone have any suggestions please?
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
List<ContentType> contentTypeList = new ArrayList<>();
contentTypeList.add(ContentType.create("application/x-dmas+json"));
contentTypeList.add(ContentType.create("application/exe"));
int idx = 0;
while(paramKeysIt.hasNext()) {
builder.addBinaryBody(key = paramKeysIt.next(), params.get(key), contentTypeList.get(idx++), params.get(key).getName());
}
HttpEntity reqEntity = builder.build();
Very strange. By POSTing my request to an echo server I am able to see that the Content-Transfer-Encoding headers are indeed absent, even though they show up clearly, and repeatedly in the debugger!
Using NetBeans IDE 8.0

Resources