java - 实现RESTful大文件上传的正确方法

标签 java file rest curl file-upload

我制作 REST API 已经有一段时间了,但我仍然被一种情况所困扰——大文件上传。我读过一些其他的 API,比如 Google Drive、Twitter 和其他文献,我有两个想法,但我不确定它们是否“合适”。准确地说,我的意思是它有点标准化,不需要太多的客户端逻辑(因为其他方将实现该客户端),或者更好的是,它可以很容易地用 cURL 调用。计划用 Java 实现它,最好是 Play Framework。

显然我需要一些文件分区和服务器端缓冲机制,因为文件很大。

因此,我得到的第一个解决方案是分段上传 (multipart/form-data)。我是这样实现的,我以前也是这样实现的,但是在客户端实际模拟一个表单对我来说总是很奇怪,特别是因为客户端必须设置文件键名,根据我的经验,这是一个问题客户有点忘记或不理解。另外, block 大小/部分大小是如何规定的?是什么阻止客户端将整个文件放在一个 block 中?

解决方案二,至少我所理解的,但没有找到实际的实现实现是“常规”POST 请求可以工作。内容应该分 block ,数据在服务器端进行缓冲。但是,我不确定这是一个正确的理解。数据实际上是如何分 block 的,上传是跨越多个 HTTP 请求还是在 TCP 级别分 block ? Content-Type 是什么?

最重要的是,这两个(或其他任何东西?)中的哪一个应该是一种客户端友好的、可广泛理解的、实现用于文件上传的 REST API 的方法?

最佳答案

我建议您查看 Amazon S3 Rest API 的分段文件上传解决方案。可以找到文档 here .

总结亚马逊使用的程序:

  1. 客户端发起分段上传请求,API返回上传id

  2. 客户端上传每个文件 block ,其中包含部分编号(以保持文件的顺序)、部分大小、部分的 md5 哈希和上传 ID;这些请求中的每一个都是一个单独的 HTTP 请求。 API 通过检查接收到的 md5 哈希值 block 与客户端提供的 md5 哈希值来验证 block ,并且 block 的大小与客户端提供的大小相匹配。 API 以 block 的标记(唯一 ID)响应。如果您将 API 部署到多个位置,您将需要考虑如何存储 block 并在以后以位置透明的方式访问它们。

  3. 客户端发出完成上传的请求,其中包含每个 block 编号的列表以及从 API 收到的关联 block 标签(唯一 ID)。 API 验证没有丢失的 block 以及 block 编号是否与正确的 block 标记匹配,然后组装文件或返回错误响应。

Amazon 还提供了中止上传并列出与上传关联的 block 的方法。您可能还需要考虑上传请求超时,如果在特定时间内未完成上传, block 将被销毁。

在控制客户端上传的 block 大小方面,您无法控制客户端决定如何拆分上传。您可以考虑为上传配置最大块大小,并为包含大于最大大小的 block 的请求提供错误响应。

我发现该过程非常适合处理 REST API 中的大型文件上传,并有助于处理与文件上传相关的许多边缘情况。不幸的是,我还没有找到一个库可以轻松地用任何语言实现这一点,因此您几乎必须自己编写所有逻辑。

关于java - 实现RESTful大文件上传的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33889410/

相关文章:

java - Kotlin:泛型和方差

java - 如果将 ArrayList 引用为 List,为什么性能会有所不同?

javascript - 如何在 Javascript 中读取和写入文件

java - 找不到类 : org. glassfish.jersey.servlet.ServletContainer

java - 如何使用 Java 下载/保存 LinkedIn 个人资料为 PDF 文件?

java - 按参数类型?

java - 无法在项目中找到文件

visual-studio - 如何在已打开的 Visual Studio 中从命令行打开文件?

java - Java 中的 REST WebService 和并发

rest - 使用带有 Sails.js 的 REST API 的 CSRF 保护