如何在 body 与 Java 的请求中创建 multipart/mixed 与 xml 的请求?
How to create multipart/mixed request with xml in the request body with Java?
下面是我想用 JAVA 创建的一个请求。
但在第一部分,我想放置 XML,而不是字段或文本,而是 XML,在第二部分 - 我要上传的文件。此外,我请求的每一部分都应该有不同的内容类型和内容配置。
那么如何为请求中的不同部分设置不同的 HTTP headers?
另外一个问题是:你能解释一下 Content-Disposition 到底是什么以及什么时候使用它吗?
--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--
我想我看到了一些东西,但我不知道如何将我的 content-disposition 放入零件中。这是我的代码:
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);
这里怎么写Content-Disposition:name="tableau_datasource";文件名="datasource-file-name"?
我的意思是,使用随您选择的语言提供的任何 HTTP 客户端 API 的多部分功能。您有点需要告诉您尝试使用哪种语言发送。但是任何有价值的 HTTP 客户端 API 都会提供这样做的可能性,而无需询问如何去做。
编辑:所以语言是 Java。使用 Apache's HttpClient 4.5 发送多部分请求相当容易。请参阅随附的示例。
编辑 2:抱歉。事实证明,毕竟通过查看示例并不能证明它是显而易见的。我发誓我记得是这样的。
假设你有:
String document;
byte[] file;
您可以通过以下方式提出此请求:
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);
产生:
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--
这应该足够接近并以与您的请求相同的方式被接受。有需要可以fine-tune
Additional question is: could you explain me what exactly is Content-Disposition and when it is used ?
一般来说,它有助于提供有关多部分当前部分的信息,这些信息只有在处于多部分的上下文中才真正有意义。
示例:给 name 部分,这样您就可以判断该部分是否包含您的 XML 文档或它是否包含您正在上传的文件(哪个也可以是 XML 文件。)
其他示例,如果通常要将其存储为文件,则指示该部分的首选 文件名。
它最常见的用法是发送带有输入文件的常规 HTML 表单。这些作为 multipart/form-data 发送,每个部分都有一个
Content-Disposition: form-data; name="name of the field defined in the HTML form"
并且文件有
Content-Disposition: form-data; name="name of the input file field"; filename="filename.ext"
请注意,Content-Disposition header 必须 以指示零件性质的标记开头。 HTML 形式是 form-data,在其他任何地方你都可以使用 attachment。您也可以定义自己的,因为从技术上讲,发送像这样的多部分消息而不是 HTML 表单或 SOAP 请求,不是标准化的,因此客户端和服务器将需要遵守为其创建的规范.
如果我们使用 MultipartEntityBuilder.create() 这将始终对数据进行编码
例如:创建如下所示的多部分将对 xml 和文件
进行编码
String document = "<tsRequest>
<datasource name="datasource-name" >
<connectionCredentials name="connection-username" password="connection-password"
embed="embed-flag" />
<project id="project-id" />
</datasource>
</tsRequest>
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();
虽然我们在这里发送 ContentType.create("text/xml") StringBody class 正在对其进行编码并发送到服务器。我看到您正在调用 tableau 服务器,tableau 将接受 xml。
Tableau 文档如下所示
注意:发布的内容不应进行编码(例如,使用 Base-64 或 UTF-8)。
请查看此文档:https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_publish.htm
找到有效的球衣客户端。要推送到画面服务器的示例球衣客户端项目:https://github.com/tableau/rest-api-samples
下面是我想用 JAVA 创建的一个请求。 但在第一部分,我想放置 XML,而不是字段或文本,而是 XML,在第二部分 - 我要上传的文件。此外,我请求的每一部分都应该有不同的内容类型和内容配置。
那么如何为请求中的不同部分设置不同的 HTTP headers?
另外一个问题是:你能解释一下 Content-Disposition 到底是什么以及什么时候使用它吗?
--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--
我想我看到了一些东西,但我不知道如何将我的 content-disposition 放入零件中。这是我的代码:
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);
这里怎么写Content-Disposition:name="tableau_datasource";文件名="datasource-file-name"?
我的意思是,使用随您选择的语言提供的任何 HTTP 客户端 API 的多部分功能。您有点需要告诉您尝试使用哪种语言发送。但是任何有价值的 HTTP 客户端 API 都会提供这样做的可能性,而无需询问如何去做。
编辑:所以语言是 Java。使用 Apache's HttpClient 4.5 发送多部分请求相当容易。请参阅随附的示例。
编辑 2:抱歉。事实证明,毕竟通过查看示例并不能证明它是显而易见的。我发誓我记得是这样的。
假设你有:
String document;
byte[] file;
您可以通过以下方式提出此请求:
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);
产生:
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--
这应该足够接近并以与您的请求相同的方式被接受。有需要可以fine-tune
Additional question is: could you explain me what exactly is Content-Disposition and when it is used ?
一般来说,它有助于提供有关多部分当前部分的信息,这些信息只有在处于多部分的上下文中才真正有意义。
示例:给 name 部分,这样您就可以判断该部分是否包含您的 XML 文档或它是否包含您正在上传的文件(哪个也可以是 XML 文件。)
其他示例,如果通常要将其存储为文件,则指示该部分的首选 文件名。
它最常见的用法是发送带有输入文件的常规 HTML 表单。这些作为 multipart/form-data 发送,每个部分都有一个
Content-Disposition: form-data; name="name of the field defined in the HTML form"
并且文件有
Content-Disposition: form-data; name="name of the input file field"; filename="filename.ext"
请注意,Content-Disposition header 必须 以指示零件性质的标记开头。 HTML 形式是 form-data,在其他任何地方你都可以使用 attachment。您也可以定义自己的,因为从技术上讲,发送像这样的多部分消息而不是 HTML 表单或 SOAP 请求,不是标准化的,因此客户端和服务器将需要遵守为其创建的规范.
如果我们使用 MultipartEntityBuilder.create() 这将始终对数据进行编码 例如:创建如下所示的多部分将对 xml 和文件
进行编码 String document = "<tsRequest>
<datasource name="datasource-name" >
<connectionCredentials name="connection-username" password="connection-password"
embed="embed-flag" />
<project id="project-id" />
</datasource>
</tsRequest>
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();
虽然我们在这里发送 ContentType.create("text/xml") StringBody class 正在对其进行编码并发送到服务器。我看到您正在调用 tableau 服务器,tableau 将接受 xml。
Tableau 文档如下所示 注意:发布的内容不应进行编码(例如,使用 Base-64 或 UTF-8)。 请查看此文档:https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_publish.htm
找到有效的球衣客户端。要推送到画面服务器的示例球衣客户端项目:https://github.com/tableau/rest-api-samples