【问题标题】:Uploading images to Spring Boot and S3 all In-Memory将图像上传到 Spring Boot 和 S3 all In-Memory
【发布时间】:2018-07-12 04:58:30
【问题描述】:

我有一个使用 Spring Boot REST 服务作为其支持 Web 服务的 Angular Web 应用程序。

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

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

似乎处理此类文件上传的标准方法是公开一个接受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 实例!

  • 有没有办法将整个配置文件图像 (MultipartFile) 保留在控制器方法的内存中?
  • 有没有办法将 MultipartFile 实例提供给 S3 的 PutObjectRequest
  • 或者这是一个糟糕的想法(如果是,为什么?!)?

【问题讨论】:

    标签: spring amazon-web-services spring-boot amazon-s3 multipart


    【解决方案1】:

    我一直在看同样的事情。基本上,您希望用户能够上传相册并从 S3 提供这些照片,并可能将它们保护起来,以便只有该用户可以上传/删除/等。

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

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

    将其提供给您的 Angular 应用(或 ionic 应用)以将图像上传到该位置。

    应该这样做。但如果我错了,请告诉我。

    我看到的唯一问题是,如果 bob 想要上传“bobs_nude_photo.jpg”并且只希望 spring security 登录的人能够看到它……那么我确定有一个 S3 解决方案吗? ?

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      这取决于您的具体情况,但通常不是首选。
      如果 - 没有多少用户同时上传图片,您的内存可能足以应付。
      否则 - 您很容易遇到内存不足的问题。

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

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

      【讨论】:

      • 感谢@Minjun Yu (+1) - 所以它看起来像一个很好的解决方案(也许)对我来说是:(1)将文件存储在 Spring 服务器上某处的 tmp 目录中和(2 ) 成功上传到 S3 后删除文件?这听起来像是最好的解决方案吗?
      • @smeeb 是的,听起来不错。还要看看 File.createTempFile()。
      猜你喜欢
      • 1970-01-01
      • 2019-09-23
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多