在嵌入式Jetty容器中运行Spring Rest应用程序。 在客户端我使用RestTemplate(尝试)。
用例:
有一个InputStream(我没有文件),我想将它发送到REST服务。
InputStream可能非常大(没有byte []!)。
到目前为止我尝试过:
将 StandardServletMultipartResolver 添加到Dispatcher上下文中;
执行servlet注册时:
ServletRegistration.Dynamic dispatcher = ...
MultipartConfigElement multipartConfigElement = new MultipartConfigElement("D:/temp");
dispatcher.setMultipartConfig(multipartConfigElement);
在客户端:
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
parts.add("attachmentData", new InputStreamResource(data) {
// hacks ...
@Override
public String getFilename() {
//avoid null file name
return "attachment.zip";
}
@Override
public long contentLength() throws IOException {
// avoid calling getInputStream() twice
return -1L;
}
}
ResponseEntity<Att> saved = restTemplate.postForEntity(url, parts, Att.class)
在服务器上:
@RequestMapping("/attachment")
public ResponseEntity<Att> saveAttachment(@RequestParam("attachmentData") javax.servlet.http.Part part) {
try {
InputStream is = part.getInputStream();
// consume is
is.close();
part.delete();
return new ResponseEntity<Att>(att, HttpStatus.CREATED);
}
}
发生了什么: 上载的InputStream已成功存储在已配置的临时文件夹(MultiPart1970755229517315824)中,零件参数在处理程序方法中正确注入。
delete()方法不会删除文件(smth仍然打开了句柄)。
无论如何,它看起来很丑陋。是否有更顺畅的解决方案?
答案 0 :(得分:3)
您想要使用HTTP的Chunked Transfer Coding。您可以通过设置SimpleClientHttpRequestFactory.setBufferRequestBody(false)
启用该功能。请参阅SPR-7909。
答案 1 :(得分:0)
您应该使用byte [],并在Web服务周围编写一个包装器,以实际发送块中的“大字符串”。在webservice中添加一个参数,该参数将指示内容的“contentID”,以便另一方知道该部分属于哪个半满的“桶”。另一个参数“chunkID”将有助于对另一侧的块进行排序。最后,如果你发送的是最后的东西,第三个参数“isFinalChunk”将被设置。这是非常奇特的功能,可以在不到100行代码中实现。
唯一的问题是你最终会对网络服务进行“n”调用,而不是只调用一次,这会聚合连接延迟等。对于实时的东西,需要更多的网络QoS,否则你应该没事。
我认为这更简单,一旦你有自己的类包装器来做这个简单的切割和粘合,如果你的服务器可以处理多个webservice调用,它可以在很大程度上扩展。