Down here is one request I want to create with JAVA. But in the first part I want to put XML, not fields or text but XML and in the second - my file which I want to upload. Also every part of my request should have different content type and content disposition.
So How to set different HTTP headers for the different parts like in the request down?
Additional question is: could you explain me what exactly is Content-Disposition and when it is used ?
--boundary-string
Content-Disposition: name="request_payload"
Content-Type: text/xml
<tsRequest>
<datasource name="datasource-name" >
<connectionCredentials name="connection-username" password="connection-password"
embed="embed-flag" />
<project id="project-id" />
</datasource>
</tsRequest>
--boundary-string
Content-Disposition: name="tableau_datasource"; filename="datasource-file-name"
Content-Type: application/octet-stream
content-of-datasource-file
--boundary-string--
I think I saw something but I dont know how to put the my content-disposition in the parts. Here is my code:
HttpClient client = HttpClientBuilder.create().build();
File file = new File("D:/qwe.txt");
HttpPost post = new HttpPost("https://test.com/datasources");
post.setHeader("X-Tableau-Auth", "RfVJIasdsadrW");
StringBody stringBody1 = new StringBody("The XML body is here!", ContentType.APPLICATION_XML);
FileBody fileBody = new FileBody(file, ContentType.APPLICATION_OCTET_STREAM);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("text1", stringBody1);
builder.addPart("upfile", fileBody);
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);
System.out.println(response);
How to put here Content-Disposition: name="tableau_datasource"; filename="datasource-file-name"?
I mean, use the multipart functionality of whatever HTTP client API is provided with your language of choice. You kind of need to tell what language you're trying to send that with. But any worthy HTTP client API will offer the possibility to do that without having to ask how to.
Edit: so the language is Java. It's fairly easy to send multipart requests with Apache's HttpClient 4.5. See the examples provided with it.
Edit 2: Apologies. Turns out it doesn't qualify as obvious to do by looking at examples after all. I swear I remember it as such.
Assuming you have:
String document;
byte[] file;
You can make this request as:
HttpEntity entity = MultipartEntityBuilder.create()
.setMimeSubtype("mixed")
.addPart(FormBodyPartBuilder.create()
.setName("request_payload")
.setBody(new StringBody(document, ContentType.create("text/xml")))
.build())
.addPart(FormBodyPartBuilder.create()
.setName("tableau_datasource")
.setBody(new ByteArrayBody(file, "datasource-file-name"))
.build())
.build();
HttpPost request = new HttpPost("http://localhost:1337/test");
request.setEntity(entity);
client.execute(new HttpHost("localhost", PORT), request);
which produces:
POST /test HTTP/1.1
Content-Length: 410
Content-Type: multipart/mixed; boundary=xA-V-5psFZxuuisERy1jKEcqzo4vYI6Kq
Host: localhost:1337
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_144)
Accept-Encoding: gzip,deflate
--xA-V-5psFZxuuisERy1jKEcqzo4vYI6Kq
Content-Disposition: form-data; name="request_payload"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
<... the doc ...>
--xA-V-5psFZxuuisERy1jKEcqzo4vYI6Kq
Content-Disposition: form-data; name="tableau_datasource"; filename="datasource-file-name"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
<... the file ...>
--xA-V-5psFZxuuisERy1jKEcqzo4vYI6Kq--
which should be close enough and accepted in the same way as what you requested. It's possible to fine-tune if necessary.
Additional question is: could you explain me what exactly is Content-Disposition and when it is used ?
Generally speaking, it helps with giving information on the current part of the multipart, information that only really make sense in the context of being in a multipart.
Example: to name the part, so that you can tell whether the part contains your XML document or whether it contains the file you're uploading (which could be an XML file too.)
Other example, to indicate the preferred filename of the part, if it is typically meant to be stored as a file.
The most common usage of it, is when sending regular HTML forms with an input file. Those are sent as a multipart/form-data, and each part has a
Content-Disposition: form-data; name="name of the field defined in the HTML form"
and the files have
Content-Disposition: form-data; name="name of the input file field"; filename="filename.ext"
Note that a Content-Disposition header must start with a token indicating the nature of the part. In HTML form that's form-data, pretty everywhere else you can use attachment. You can also define your own since technically, sending multipart messages like this one without it being a HTML form or a SOAP request, isn't standardized so the client and the server will need to comply to a specification created for it.