How set custom 'Content-Disposition' Header in POST request in Java? - java

The server I am sending a POST request to requires extra parameters in the Content-Disposition field that are easily added in C# code, but I am struggling to replicate this functionality in Java.
The working C# code:
using (var content = new MultipartFormDataContent()) {
var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes("filepath"));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "file",
FileName = "file.zip.encrypted",
};
fileContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("Type", "CSV"));
fileContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("Token", jwt));
content.Add(fileContent);
var requestUri = "url";
var result = client.PostAsync(requestUri, content).Result;
When I print the above request headers the Content-Disposition header looks like:
Content-Disposition: form-data; name=file; filename=file.zip.encrypted; Type=CSV; Token=jwt
Attempting to replicate this POST request in Java Apache Http:
File file = new File("filepath");
String headerValue = "form-data; name=file; filename=\"file.zip.encrypted\"; Type=\"CSV\"; Token=\""+jwtToken+"\"";
try (CloseableHttpClient client2 = HttpClients.createDefault()) {
HttpPost post2 = new HttpPost(url);
HttpEntity entity = MultipartEntityBuilder.create().addPart("file", new FileBody(file)).build();
post2.setHeader("Content-Disposition", headerValue);
post2.setEntity(entity);
try (CloseableHttpResponse response2 = client2.execute(post2)) {
System.out.println(response2.toString());
}
}
However, when I print the Headers in this request, only the name and filename fields are captured, and not the other parameters required in the Content-Disposition header. This is leading to Internal Server Error responses, as the Header does not contain the required parameters. (tried with and without the added quotes around field values)
Content-Disposition: form-data; name="file"; filename="file.zip.encrypted"
Any help getting the C# POST request behavior replicated in Java would be greatly appreciated, thanks!

Related

OkHttp3 response string show html file instaed of download file data

I using Okhttp3 for download file from server in android application. my link is http://www.webweb.infinityfreeapp.com/lichi/download.php?path=Add.jpg it download file in firefox, chorme smoothly, while in okhttp3 response string shows
<html><body><script>document.cookie="_test=9e105a99e90025d241c180c29fad3231 ; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/" ;document.location.href="http://www.webweb.infinityfreeapp.com/lichi/download.php?path=Add.jpg&i=1";</script></body></html>
but i feel response string has Add.jpg file data. so, what can i change in okhttp3 code or php code that i gather App.jpg data in response string of okhttp3
Php Code
if(isset($_GET['path']))
{
$url = $_GET['path'];
$type = "application/pdf";
$completePath = "http://www.webweb.infinityfreeapp.com/lichi/";
$visibleName = "$url";
$completePath .= $url;
// Force download
header("Content-disposition: attachment; filename=$visibleName");
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: $type\n");
// header("Content-Length: ".filesize($completePath));
header("Pragma: no-cache");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");
readfile($completePath);
die();
}
I comment Content-Length because it crash system in uncomment
Java code
OkHttpClient client = new OkHttpClient();
String url = "http://www.webweb.infinityfreeapp.com/lichi/download.php?path=Add.jpg";
Call call = client.newCall(new Request.Builder().url(url).get().build());
Response response = call.execute();
if (response.code() == 200 || response.code() == 201) {
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++)
Log.d(LOG_TAG, responseHeaders.name(i) + ": " + responseHeaders.value(i));
String str = response.body().string();
}
Here str contain above html file information instead Add.jpg file data. so please give answer
good question
Autually if we send a get request to
http://www.webweb.infinityfreeapp.com/lichi/download.php?path=Add.jpg
we get the right resutl just like
<html><body><script>document.cookie="_test=9e105a99e90025d241c180c29fad3231 ; expires=Thu, 31-D...";</script></body></html> .
we can get a file in browser, because browser can parse html ,
when browser get the string result which is a html page, it create another request with a new Header (Cookie=_test=9e105a99e90025d241c180c29fad3231), and with the Cookie, we get an image file from server.
Thanks for quick and good solution.
i just add header as:-
.header("Cookie", "_test=9e105a99e90025d241c180c29fad3231")
and send again with above code, actual result come

How to read and parse a multipart response as a stream?

I am creating a java process to download WebEx recordings using their NBR API's NBRFileOpenService call. It returns a multipart response with the recording file contents attached. I have it somewhat working with the code below. However, when the recording file is large enough, I get OutOfMemoryError exception.
It is quite common for the recordings to be large and if the API only returned the file alone, I could just stream the download, however I'm not so sure how I can safely handle the multipart response. So I'm wondering if there is any way to read the file metadata as well as save the binary content to a file without holding the entire response in memory.
API Response Format:
------=_Part_674_458057647.1593732813745
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <AD79B5747EFC01CDDA9A281BA8CDEF0C>
[SOAP RESPONSE]
------=_Part_674_458057647.1593732813745
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <C498AB4664B57130F869695A1C5B584E>
[FILE METADATA]
------=_Part_674_458057647.1593732813745
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <003D9EBA1E491CE2E9E5903C996EFD4C>
[BINARY FILE CONTENT]
------=_Part_674_458057647.1593732813745--
My Code:
public void retrieveRecordingFile(String uri, String recordId, String serviceType) throws Exception {
HttpClient httpClient = generateHttpClient();
HttpPost httpPost = new HttpPost(uri);
httpPost.addHeader("Content-Type", ContentType.APPLICATION_XML.getMimeType());
httpPost.addHeader("SOAPAction", "NBRFileOpenService");
String requestXml = buildNBRDownloadFileXml(recordId, serviceType);
HttpEntity httpEntity = new ByteArrayEntity(requestXml.getBytes(Charset.forName("UTF-8")));
httpPost.setEntity(httpEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
MimeMultipart mimeMultipart = new MimeMultipart(new ByteArrayDataSource(httpResponse.getEntity().getContent(), "multipart/form-data"));
String filename = null;
File targetFile = null;
for (int i = 0; i < mimeMultipart.getCount(); i++) {
if (i == 1) {
filename = retrieveFileName(mimeMultipart.getBodyPart(i).getInputStream());
} else if (i == 2) {
targetFile = new File(DOWNLOAD_DIR + filename);
FileUtils.copyInputStreamToFile(mimeMultipart.getBodyPart(i).getInputStream(), targetFile);
}
}
}
}
Any help is truly appreciated.

Windows Computer Vision API - Image Format Invalid for Image In Binary - Java

I am facing an issue with Windows Computer Vision API. If I send a request with contentType = application/json and image URL in JSON request body things work fine but on sending a binary image(base 64 encoded) with contentType = application/octet-stream it gives me ImageFormatInvalid in the response.
Any help is much appreciated. Thank you!
Code:
final String binaryData = "data:image/jpeg;base64, /9............
ByteArrayEntity requestEntity = new ByteArrayEntity(binaryData.getBytes(),
ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(requestEntity);
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
Response: InvalidImageFormat
It seems I was generating the binary incorrectly.
Worked when made changes as below:
byte[] decodedString = Base64.decodeBase64(binaryData);
ByteArrayEntity requestEntity = new
ByteArrayEntity(decodedString,ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(requestEntity);

How to remove Accept-char header from HTTP post request

I am using rest template for creating HTTP post request . But request contain by default added Accept-char header with huge Content . Please suggest how to exclude addition of that header. Below is the code i am using:
HttpHeader header= new HttpHeader();
RestTemplate template = new RestTemplate();
header.setContentType("application/xml");
String body=" content of body ";
HttpEntity<string> request=new HttpEntity<string> (body,header);
template.postForObject(URL,request,String.class);
This should remove 'Accept-Charset' header:
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
stringHttpMessageConverter.setWriteAcceptCharset(false);
restTemplate.getMessageConverters().add(0, stringHttpMessageConverter);

Mailgun API: Sending Inline Image with Spring's RestTemplate

The goal is to send an email with inline image. Everything is working well, except the image is not appearing in the email.
My approach is based on this Jersey-example of Mailgun's User Guide.
public static ClientResponse SendInlineImage() {
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("api",
"YOUR_API_KEY"));
WebResource webResource =
client.resource("https://api.mailgun.net/v3/YOUR_DOMAIN_NAME" +
"/messages");
FormDataMultiPart form = new FormDataMultiPart();
form.field("from", "Excited User <YOU#YOUR_DOMAIN_NAME>");
form.field("to", "baz#example.com");
form.field("subject", "Hello");
form.field("text", "Testing some Mailgun awesomness!");
form.field("html", "<html>Inline image here: <img src=\"cid:test.jpg\"></html>");
File jpgFile = new File("files/test.jpg");
form.bodyPart(new FileDataBodyPart("inline",jpgFile,
MediaType.APPLICATION_OCTET_STREAM_TYPE));
return webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).
post(ClientResponse.class, form);
}
However, I need to use Spring's RestTemplate.
This is what I've got so far:
RestTemplate template = new RestTemplate();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
// ... put all strings in map (from, to, subject, html)
HttpHeaders headers = new HttpHeaders();
// ... put auth credentials on header, and content type multipart/form-data
template.exchange(MAILGUN_API_BASE_URL + "/messages", HttpMethod.POST,
new HttpEntity<>(map, headers), String.class);
The remaining part is to put the *.png file into the map. Not sure how to do that. Have tried reading all its bytes via ServletContextResource#getInputStream, but without success: Image is not appearing in the resulting e-mail.
Am I missing something here?
This turned out to be a case where everything was set up correctly, but only a small detail prevented it from working.
map.add("inline", new ServletContextResource(this.servletContext,
"/resources/images/email-banner.png"));
For Mailgun you need to use the map-key "inline". Also, the ServletContextResource has a method getFilename(), which is used to resolve against the image tag. Thus, the image tag should have the following content id:
<img src="cid:email-banner.png"/>

Categories