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

Uploading images to Spring Boot and S3 all In-Memory

我有一个 Angular 网络应用程序,它使用 Spring Boot REST 服务作为其后备网络服务。

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

正在看几个SpringBoot/file上传教程:

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

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

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

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

File file = new File(uploadFileName);
s3client.putObject(new PutObjectRequest(bucketName, keyName, file));

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

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

Is there a way to keep the entire profile image (MultipartFile) in-mempory inside the controller method?

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

Is there a way to feed (maybe via serialization?!) a MultipartFile instance to S3's PutObjectRequest?

不,根据 S3 的 API 文档,S3 无法为您 after/during 上传反序列化为图像文件。

Or is this all a terrible idea (if so, why?!)?

这取决于您的具体情况,但通常不是首选。
如果——同时上传图片的用户不多,你的内存大概够应付了。
否则 - 您很容易遇到内存不足的问题。

如果你坚持这样做,S3API可以上传一个InputStream(如果我没记错的话)。您可以将多部分文件转换为 InputStream.
This SO thread talks about uploading to S3 with InputStream

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

我一直在看同样的东西。基本上,您希望用户能够上传相册并从 S3 提供这些照片,并且可能会保护它们,因此只有该用户可以 upload/delete/etc.

我相信更简单的答案是在 spring 引导中从 S3 获得预签名 URL。 https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObjectJavaSDK.html

这基本上为您提供了一个定义存储桶的令牌和对象键(“/bobs_profile/smiling_bob.jpg”)以及上传该图像的时间限制。

将其提供给您的 angular 应用程序(或离子应用程序)以将图像上传到该位置。

应该可以了。但如果我错了,有人告诉我。

我看到的唯一问题是 bob 是否想要上传 "bobs_nude_photo.jpg" 并且只希望 spring 安全登录的人能够看到它...嗯我确定有一个 S3 解决方案??