如何创建包含多部分表单数据的可重复 POST 请求?

Posted

技术标签:

【中文标题】如何创建包含多部分表单数据的可重复 POST 请求?【英文标题】:How to create a repeatable POST request that contains multipart-form-data? 【发布时间】:2016-02-29 01:55:17 【问题描述】:

我正在尝试创建一个 POST 请求,其中包含需要 NT Credentialsmultipart-form-data。身份验证请求导致POST 被重新发送,我得到一个不可重复的实体异常。

我尝试包装使用BufferedHttpEntity 生成的MultipartContent 实体,但它抛出NullPointerExceptions

final GenericUrl sau = new GenericUrl(baseURI.resolve("Record"));
final MultipartContent c = new MultipartContent().setMediaType(MULTIPART_FORM_DATA).setBoundary("__END_OF_PART__");
final MultipartContent.Part p0 = new MultipartContent.Part(new HttpHeaders().set("Content-Disposition", format("form-data; name=\"%s\"", "RecordRecordType")), ByteArrayContent.fromString(null, "C_APP_BOX"));
final MultipartContent.Part p1 = new MultipartContent.Part(new HttpHeaders().set("Content-Disposition", format("form-data; name=\"%s\"", "RecordTitle")), ByteArrayContent.fromString(null, "JAVA_TEST"));
c.addPart(p0);
c.addPart(p1);

ByteArrayContent 的文档说

AbstractInputStreamContent 的具体实现,根据字节数组的内容生成可重复的输入流。

使所有部分可重复并不能解决问题。因为这段代码 System.out.println("c.retrySupported() = " + c.retrySupported()); 输出c.retrySupported() = true

我找到了以下文档:

1.1.4.1。可重复的实体 一个实体可以是可重复的,这意味着它的内容可以被多次读取。这只有 self 才有可能 包含的实体(如 ByteArrayEntity 或 StringEntity)

我现在通过提取字符串内容将我的MultipartContent 转换为具有multi/part-form 媒体类型的ByteArrayContent,但仍然出现相同的错误!

但是当我尝试调用request.execute() 时,我仍然收到以下异常。

Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.

那么我该如何说服ApacheHttpTransport 创建一个可重复的实体?

【问题讨论】:

【参考方案1】:

如果多部分实体中所有部分的内容长度已知(返回为非负值),则该实体将被视为可重复。使多部分实体可重复的最简单方法是使其所有部分都可重复。

【讨论】:

1.1.4.1。可重复的实体 一个实体可以是可重复的,这意味着它的内容可以被多次读取。这仅适用于自包含实体(如 ByteArrayEntity 或 StringEntity) Sigh 我知道这一段说什么,因为我写了它。自己看:hc.apache.org/httpcomponents-client-4.5.x/httpmime/xref/org/…hc.apache.org/httpcomponents-client-4.5.x/httpmime/xref/org/… 您的回答无效,我已经提供了可重复的部件。在我发现该警告后,我将MultipartContent 序列化为ByteArrayContent,并使用MulitpartContent 媒体类型。仍然得到同样的错误。我已经用所有这些细节更新了这个问题,关于我尝试了什么以及为什么/如何仍然失败。 如果位于 Apache HttpClient 之上的库不使用其原生 MIME 框架,而只是将不可重复的实体传递给它,则 HttpClient 无能为力。【参考方案2】:

我必须修改从HttpContent 继承的所有类,以便它们可以正确地使用.retrySupported() 报告回来,以便在输入ApacheHttpTransport 代码时它会正确地创建可重复的内容。

这些更改是针对版本 1.20.0 进行的,因为这是我使用的。我正在提交针对dev 分支HEAD 的拉取请求,因此希望这个或其中的某个版本能够进入下一个版本。

Here are the modifications that need to be merged in.

【讨论】:

以上是关于如何创建包含多部分表单数据的可重复 POST 请求?的主要内容,如果未能解决你的问题,请参考以下文章

具有特定 JSON 要求的多部分表单数据 POST

解析Servlet中传入的多部分/表单数据参数的便捷方法[重复]

Nodejs POST 请求多部分/表单数据

如何发布具有多部分/表单数据编码的数组?

Facebook API 使用带有多部分表单数据的 HTTP POST 请求的错误响应

PHP多部分表单数据PUT请求?