通过播放框架应用程序将文件上传到S3,而无需"触摸"磁盘

时间:2014-03-18 05:12:10

标签: java file-upload playframework amazon-s3 playframework-2.2

我必须实现一个服务器,让一些用户可能将大量文件(数千兆字节的文件)上传到S3(但他们不知道它是S3)。我已经在Python中实现了类似的东西,并使用Play框架实现了基本实现。

现在我的上传功能如下:

public Result uploadFile() {
      List<Http.MultipartFormData.FilePart> files = request().body().asMultipartFormData().getFiles();
      if (CollectionUtils.isNotEmpty(files)) {
          Bucket bucket = MY_BUCKET;
          UUID timeuuid;
          Promise<UploadResult> promise;
          ObjectNode responseMessage = Json.newObject();  
          for (Http.MultipartFormData.FilePart file : files) {
              timeuuid = TimeUUID.now();
              promise = Promise.promise(new UploadFunction(timeuuid, bucket, file.getFile(), obtainS3Connection()));
              responseMessage.set(file.getFilename(), TextNode.valueOf(timeuuid.toString()));
          }
          return accepted(responseMessage);
      } else {
          return badRequest("files empty");
      }
}

我并不担心上传代码本身,实际上我已经多次实现了它。我担心的是让它变得如此Play!不将文件保存到磁盘,并且发送的文件只“通过”我的服务器而不写入磁盘(即使是临时文件)。我有一些处理涉及到某些内容的“客户端”加密,我可以做一个流。

我想知道Play是否已经这样做了?或者我将如何实现这一目标?

我假设Play(以及我之前版本的此服务中的Django)的作用是:

Upload --> Play       MyProcessing -------> S3
               \     /
                \   /
                 Disk

我希望它能做什么:

Upload --> Play --> MyProcessing -------> S3

我想这样做的原因是我希望有可能在具有非常小的磁盘的实例上部署我的服务,并且我还希望保证在上载后没有人能够找到未加密的文件(如果我选择加密它)。

更新:我现在还没有放弃......

我找到了一些不幸使用Scala的可能解决方案。它们都围绕着与此讨论相同的主题: Play 2.x : Reactive file upload with Iteratees

我想知道这是否可以使用Java(我是我公司中唯一知道Scala的人,所以我不能推出一些我能成为唯一能够对其进行维护的人...因为有时候我希望休息或继续其他项目。)

1 个答案:

答案 0 :(得分:1)

我从未用Play做过这个,但我在Java中做过类似的事情。我们成功的途径是直接将文件发布到S3。基本上,您所做的是为用户生成上传表单,其中服务不提供帖子URL,但亚马逊用户浏览器直接上传到S3。

在上传成功时,S3将在成功上载对象时返回状态代码为200的空文档。在我们的例子中,我们通过jQuery执行post调用并等待帖子上的jQuery成功处理程序,然后才更新我们的系统数据库。或者,可以指定一个重定向表单字段,其中包含用户在成功上载后重定向到的URL。

有关详细信息,请访问: http://doc.s3.amazonaws.com/proposals/post.html