将图像上传到 Spring Boot 和 S3 all In-Memory

sme*_*eeb 5 spring multipart amazon-s3 amazon-web-services spring-boot

我有一个 Angular webapp,它使用 Spring Boot REST 服务作为其支持的 web 服务。

我正在为用户添加“个人资料”功能,作为其中的一部分,我想建立一个端点,允许用户为自己上传个人资料图像并立即将这些文件上传到 S3(我将在其中托管所有图像)。

看几个Spring Boot/文件上传教程:

似乎处理此类文件上传的标准方法是公开一个接受MultipartFiles如下的控制器端点:

@RestController
@RequestMapping("/v1/profiles")
public class ProfileController {
    @PostMapping("/photo")
    public ResponseEntity uploadProfilePhoto(@RequestParam("mpf") MultipartFile mpf)
        // ...
}
Run Code Online (Sandbox Code Playgroud)

查看所有这些代码,我无法判断该MultipartFile实例是否在内存中,或者 Spring 是否将其位置设置/tmp在磁盘上的某个位置(可能在?下)。

查看AWS S3 Java SDK 教程,上传基于磁盘的文件的标准方法似乎是这样的:

File file = new File(uploadFileName);
s3client.putObject(new PutObjectRequest(bucketName, keyName, file));
Run Code Online (Sandbox Code Playgroud)

所以看起来我必须在磁盘上有一个文件才能上传到 S3。

我想知道是否有办法将所有内容保存在内存中,或者这是否是一个坏主意,我应该坚持使用磁盘/File实例!

  • 有没有办法将整个配置文件图像(MultipartFile)保存在控制器方法中的内存中?
  • 有没有办法MultipartFile向 S3提供(也许通过序列化?!)一个实例PutObjectRequest
  • 或者这都是一个糟糕的主意(如果是这样,为什么?!)?

Min*_* Yu 1

有没有办法将整个配置文件图像(MultipartFile)保留在控制器方法内的内存中?

不,没有办法将图像文件保存在内存中,因为java中的File对象代表文件系统中的路径。

有没有办法将 MultipartFile 实例提供给 S3 的 PutObjectRequest(也许通过序列化?!)?

不,从 S3 的 API 文档来看,S3 无法在上传之后/期间为您反序列化为图像文件。

或者这都是一个糟糕的主意(如果是这样,为什么?!)?

这取决于您的具体情况,但通常不是首选。
如果 - 同时上传图像的用户不多,那么您的内存可能足以处理。
否则 - 你很容易出现内存不足的问题。

如果你坚持这样做,S3 API 可以上传一个InputStream(如果我没记错的话)。您可以将多部分文件转换为InputStream.
这个SO线程谈论使用InputStream上传到S3

您还可以查看File.createTempFile()如何创建临时文件。