Spring将非多部分文件作为流上载
我正在使用SpringBoot1.2.5,我想将原始二进制文件上传到控制器。文件大小可能很大,因此我不想将整个请求保存在内存中,而是流式传输文件,事实上,文件是在传输开始时生成的,因此客户端甚至不知道文件的大小。我看到了一个如何使用多部分编码的文件上传执行类似操作的示例。然而,我不想要一个多部分编码的上传,只是一个原始的字节流。我似乎找不到在spring中处理此用例的方法。您可以使用Spring将非多部分文件作为流上载,spring,file-upload,spring-boot,binaryfiles,Spring,File Upload,Spring Boot,Binaryfiles,我正在使用SpringBoot1.2.5,我想将原始二进制文件上传到控制器。文件大小可能很大,因此我不想将整个请求保存在内存中,而是流式传输文件,事实上,文件是在传输开始时生成的,因此客户端甚至不知道文件的大小。我看到了一个如何使用多部分编码的文件上传执行类似操作的示例。然而,我不想要一个多部分编码的上传,只是一个原始的字节流。我似乎找不到在spring中处理此用例的方法。您可以使用HttpServletRequestinputstream。 请注意,如果您有任何过滤器预处理请求并使用input
HttpServletRequest
inputstream。请注意,如果您有任何过滤器预处理请求并使用inputstream,那么这可能不起作用
@ResponseBody
@RequestMapping(path="fileupload", method = RequestMethod.POST, consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void fileUpload(HttpServletRequest request) throws IOException {
Files.copy(request.getInputStream(), Paths.get("myfilename"));
}
我想和大家分享一些小发现,也许会对大家有所帮助 我使用spring的
MultipartFile
上传大文件,担心spring会将内容存储在内存中。因此,我决定使用getInputStream()
方法,希望这样可以将文件直接流式传输到所需的位置:
@PostMapping("/upload")
public ResponseEntity<?> uploadFile(@RequestPart MultipartFile file) throws FileNotFoundException, IOException{
FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(new File("/storage/upload/", file.getOriginalFilename())));
return ResponseEntity.ok("Saved");
}
最后,如果您只想将文件上传到特定的目录/文件,您可以使用此解决方案,它将与手动流式传输文件一样快
重要提示:有两个transferTo()
方法,一个接收路径
,另一个接收文件
。不要使用接收路径的路径,因为它会复制文件并且速度较慢
EDIT1:
我使用HttpServletRequest
测试了该解决方案,但它仍将存储一个临时文件,除非您设置spring configspring.servlet.multipart.enabled=false
。使用multipathttpservletrequest
的解决方案也是如此
我发现使用我找到的解决方案有三个主要好处:
很简单
它允许您一次处理多个文件,您只需将多个@RequestPart MultipartFile
添加到控制器方法中即可
它允许您轻松处理带有文件的响应主体
public ResponseEntity上载文件(@RequestPart@Valid MyCustomPOJO pojo、@RequestPart MultipartFile file1、@RequestPart MultipartFile file2、@RequestPart MultipartFile file3)
以下是我为测试一些概念而创建的测试项目的URL,包括:
需要澄清的是,在上载过程中调用此处理程序。这意味着没有数据存储在临时文件中,并且在调用时整个文件都不在内存中,对吗?@cmaynard在处理请求头后输入该方法。然后得到请求主体的流。您可能有一个servlet过滤器,它使用类似于TeeInputStream
的东西来保留请求主体的缓冲区,但在默认的spring引导中,SpringMVC项目你不应该有这样的东西。虽然你的研究很有趣,也很有价值,但它与当前关于流式上传/非多方上传的主题无关,谢谢你的回答。我可以使用多部分文件的输入流而不将整个文件保存在任何地方吗?
@PostMapping("/upload")
public ResponseEntity<?> uploadFile(@RequestPart MultipartFile file) throws FileNotFoundException, IOException{
file.transferTo(new File("/storage/upload/", file.getOriginalFilename()));
return ResponseEntity.ok("Saved");
}
public ResponseEntity<?> uploadFile(@RequestPart @Valid MyCustomPOJO pojo, @RequestPart MultipartFile file1, @RequestPart MultipartFile file2, @RequestPart MultipartFile file3)