如何使用Java在请求体中使用xml创建multipart / mixed请求?

时间:2018-03-09 14:54:17

标签: xml multipart content-disposition

这里是我想用JAVA创建的一个请求。 但是在第一部分中我想放XML,而不是字段或文本而是XML,而在第二部分 - 我要上传的文件。此外,我的请求的每个部分都应具有不同的内容类型和内容处置。

那么如何为请求中的不同部分设置不同的HTTP标头?

另外一个问题是:你能解释一下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--

我想我看到了一些东西,但我不知道如何把我的内容 - 性格放在部分中。这是我的代码:

    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”;文件名= “数据源文件名”?

2 个答案:

答案 0 :(得分:1)

如果我们使用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类对此进行编码并发送到服务器。我看到您正在调用tableau服务器,并且tableau将接受xml。

Tableau文档说如下 注意:不应对发布的内容进行编码(例如,使用Base-64或UTF-8)。 请检查此文档:https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_publish.htm

找到有效的球衣客户。泽西客户端项目示例,以推送到tableau服务器:https://github.com/tableau/rest-api-samples

答案 1 :(得分:0)

我的意思是,使用您选择的语言提供的任何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--

应该足够接近并以与您请求的方式相同的方式接受。如有必要,可以进行微调。

  

另外一个问题是:你能解释一下Content-Disposition究竟是什么以及何时使用它?

一般来说,它有助于提供有关多部分当前部分的信息,这些信息只有在多部分的背景下才真正有意义。

示例:将命名部分,以便您可以判断该部分是否包含您的XML文档,或者它是否包含您要上载的文件(也可能是XML文件。)< / p>

其他示例,表示部件的首选文件名,如果它通常意味着存储为文件。

最常见的用法是使用输入文件发送常规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标头必须以表示该部件性质的标记开头。在HTML表单中, form-data ,在其他任何地方都可以使用附件。您也可以定义自己的技术,因为在没有HTML表单或SOAP请求的情况下发送像这样的多部分消息是不标准化的,因此客户端和服务器将需要遵守为其创建的规范。