简体   繁体   中英

REST Service - Multipart Post (JSON and File) as stream on https using Jersey

I have a REST Service on https connection that accepts file upload as multipart (ie metadata of the file and file itself)

How can I use Jersey (for websphere) or HttpClient to call REST service and send file as multipart. I want send file as multiple streams of different sizes because we can have file more than 1GB. Moreover, the REST service is using Windows NT authentication for authorization and is on https.

Can anyone give example how I can achieve this? I have used multipart httpClient. Sending it as a stream does not work. Below is my code using httpClient 4.5.2

====================================

InputStream stream = new FileInputStream("test.doc");

MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setStrictMode();

InputStreamBody streamBody = new InputStreamBody(stream, docHandler.getFilename());

FormBodyPart filePart = FormBodyPartBuilder.create()
                .setName("Binary")
                .addField(Constants.RETRIEVAL_NAME_FIELD, "test.doc")               
                .addField("Content-Type",docHandler.getContentType())
                .setBody(streamBody)
                .build();
entityBuilder.addPart(filePart);

HttpPost httpPostRequest = new HttpPost();
httpPostRequest.setEntity(entityBuilder.build());

httpClient.execute(httpPostRequest);

==================================== But when I execute this code, I am getting following error

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

Any idea why I am getting this error. If I convert stream to byte array and use ByteArrayBody instead, then it works fine but I noticed in Fiddler that three request calls are being made to the server and in every call the entire content of the file is being copied. So, if my file is of 1GB then entire content will be sent to the server three times.

Firstly, how can I achieve sending large file in chunks or multiple streams so that entire file is not sent in one call. Secondly, is there a way to avoid having 3 calls to the server for NTLM authentication?

Any pointers?

Cheers!

The Exception occurs because InputStreamBody is not repeatable (especially for large streams). A general InputStream can be read from only once.

FileBody is repeatable, as a File can be read from multiple times.

One reason for the repeatable reads may be the (NTLM)authorisation(did not check this).

You may avoid this by doing the first two NTML authorisation steps before the actual request and setting/sending the Authorization: NTLM <base64-encoded type-3-message> header, but that does not solve the problem, because the network may not be reliable enough and you have to retry anyway.

You basically have two options:

  1. use repeatable ContentBody implementations only like FileBody or own repeatable ContentBody instance.
  2. make sure the request does not need to be retried.

Please note the latter is not always possible . As mentioned before request retries due to authentication failures can be avoided, but those due to I/O errors cannot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM