关于提高文件上传的内存和性能- struts 1



我们有struts 1.1遗留MVC代码,在一个"非spring ";J2EE应用程序。下面的代码位于一个动作/表单bean中。此代码表示包含多个部分的HTTP Post的接收者。

private org.apache.struts.upload.FormFile dataFile;
...
byte[] file_bytes = null;
try {
is = this.dataFile.getInputStream();
file_bytes = IOUtils.toByteArray(is);
...
} ...

由于某些原因,早期与文档存储库的集成使用了字节数组。十年前,我想人们通常不会通过(http)网站上传更大的文件。在最近的用例中,用户(可能)上传大于1GB的文档。我不认为在内存中保持这么大的字节数组是一个好主意。根据需要,甚至可能有多个用户同时进行上传,其中一些用户正在上传更大的文件。

最近我们编写了一个spring boot rest api应用程序,作为访问云存储的适配器,其中的上传端点是这样的:

@RequestMapping(value = "/{doctype}/{docid}/upload", method = RequestMethod.POST, consumes = { "multipart/form-data" })
public ResponseEntity uploadFile(
@PathVariable String doctype,
@PathVariable String docid, 
@RequestParam("file") MultipartFile file,
@RequestParam("metadata") String docMetadata) {    
...
}
在struts v1.1 MVC JEE应用程序中,我们最终将调用上述spring引导rest端点(将文档上传到云存储)。通过阅读上面的(rest端点)代码,我认为,我们可以将内容流到这个rest端点(使用常规java代码)。

沿着这条线,我正在考虑两个选项中的一个。

选项1。保持struts上传的原样,并且只做更改以避免在内存中保存字节数组,

1.1。保持输入流(来自请求)直到调用文档存储库适配器的代码,然后对其进行流处理—我不确定这是否可行。

1.2。在struts action/form-bean中,将流存储到磁盘中,然后在调用文档存储库适配器方法时,读入流并发送…

选项2。将struts操作更改为常规servlet,以接收上传文件,并使用apache commons文件上传,并使用磁盘存储或流选项。然后流到spring boot rest api端点。

我对这两者之间的优势感到困惑(而不是在内存中保存整个字节数组)

这里解决你的问题是,做文件上传不使用巨大的内存。对于这个,你已经得到了问题的解。让我添加更多细节的解决方案选项。

  1. 获取文件并将其放到磁盘上。为此,利用Java IO装饰器模式。表示HttpRequest——>BufferedReader——比;FileWriter,确保BufferedReader有固定的字节大小。在这里,你可以利用Java NIO (Channels, Buffer…等)来进行更高效的非阻塞IO处理。它有助于接受使用相同配置上传的更多文件。https://examples.javacodegeeks.com/core-java/nio/java-nio-large-file-transfer-tutorial/

2。反应性编程。弹簧5反应器支撑端对端(客户端->RESETAPI——比;应用程序中的数据库响应式处理。因此,你可以利用Spring webflux和WebClient进行非阻塞、异步流上传文件。我建议这样做。https://www.baeldung.com/spring-webclient-upload-file

现在选择一个选项,而不是增强旧的/遗留的struts,使用最新的基于Spring的端点。

最新更新