user177800
user177800

Reputation:

How to create a repeatable POST request that contains multipart-form-data?

I am trying to create a POST request that contains multipart-form-data that requires NT Credentials. The authentication request causes the POST to be resent and I get a unrepeatable entity exception.

I tried wrapping the MultipartContent entity that is produced with a BufferedHttpEntity but it throws 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);

The documentation for ByteArrayContent says

Concrete implementation of AbstractInputStreamContent that generates repeatable input streams based on the contents of byte array.

Making all the parts repeatable does not solve the problem. Because this code System.out.println("c.retrySupported() = " + c.retrySupported()); outputs c.retrySupported() = true.

I found the following documentation:

1.1.4.1. Repeatable entities An entity can be repeatable, meaning its content can be read more than once. This is only possible with self contained entities (like ByteArrayEntity or StringEntity)

I have now converted my MultipartContent to a ByteArrayContent with a multi/part-form media type by extracting the string contents and still get the same error!

But I still get the following exception when I try and call request.execute().

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

So how do I go about convincing the ApacheHttpTransport to create a repeatable Entity?

Upvotes: 7

Views: 1844

Answers (2)

user177800
user177800

Reputation:

I had to modify all the classes that inherited from HttpContent so that they would report back correctly with .retrySupported() so that the when the ApacheHttpTransport code was entered it would create repeatable content correctly.

The changes were made against version 1.20.0 because that is what I was using. I am submitting a pull request against dev branch HEAD so hopefully, this or some version of this will make it into the next release.

Here are the modifications that need to be merged in.

Upvotes: 5

ok2c
ok2c

Reputation: 27613

If content length of all parts in multipart entity is known (returned as a non negative value) the entity will be treated as repeatable. The easiest way to make multipart entity repeatable is to make all its parts repeatable.

Upvotes: 0

Related Questions