我在https连接上有一个REST服务,它接受文件上传为多部分(即文件和文件本身的元数据)
如何使用Jersey(用于websphere)或HttpClient调用REST服务并将文件作为multipart发送。我希望将文件作为多个不同大小的流发送,因为我们可以拥有超过1GB的文件。此外,REST服务使用Windows NT身份验证进行授权,并且位于https上。
任何人都可以举例说明我是如何实现这一目标的吗?我用过多部分httpClient。将其作为流发送不起作用。下面是我使用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);
==================================== 但是当我执行此代码时,我收到以下错误
org.apache.http.client.NonRepeatableRequestException:无法使用不可重复的请求实体重试请求
知道我为什么会收到此错误。如果我将流转换为字节数组并使用ByteArrayBody,那么它工作正常但我注意到在Fiddler中正在向服务器发出三个请求调用,并且在每次调用中都会复制文件的整个内容。因此,如果我的文件是1GB,那么整个内容将被发送到服务器三次。
首先,如何在块或多个流中实现发送大文件,以便在一次调用中不发送整个文件。其次,有没有办法避免3次调用服务器进行NTLM身份验证?
任何指针?
干杯!
答案 0 :(得分:0)
发生异常是因为InputStreamBody
不可重复(特别是对于大型流)。一般InputStream
只能读一次。
FileBody
是可重复的,因为可以多次读取文件。
可重复读取的一个原因可能是(NTLM)授权(没有检查)。
您可以通过在实际请求和设置/发送之前执行前两个NTML授权步骤来避免这种情况
Authorization: NTLM <base64-encoded type-3-message>
标题,但这并不能解决问题,因为网络可能不够可靠,无论如何都必须重试。
您基本上有两个选择:
ContentBody
实施,例如FileBody
或拥有可重复的ContentBody
实例。请注意后者并非总是可以。如前所述,可以避免由于身份验证失败而导致的请求重试,但由于I / O错误导致的重试不能。