繁体   English   中英

Play框架:如何为文件上传实现REST API

[英]Play Framework: How to implement REST API for File Upload

我正在使用Play 2开发REST API,并且想知道如何实现文件上传功能。

我已经阅读了Play官方文档,但它仅提供了一个multipart/form-data示例,而我的后端未提供任何形式...它仅包含一个REST API,供JavaScript客户端或其他任何方式调用。

也就是说,实现这种API的正确方法是什么? 我应该实现PartHandler然后仍然使用mutipartFormData解析器吗? 如何将文件内容传递给API? 关于此主题是否有详尽的示例?

任何帮助将非常感激。

您应该查看BodyParsers: http ://www.playframework.com/documentation/2.2.x/ScalaBodyParsers

您尝试做的事情并不特别复杂,尤其是当您仅处理适合内存的较小文件时。 毕竟,上传文件只是将文件作为POST正文或类似内容发送。 它与在请求中接收一些XML或JSON没有什么不同。

希望这可以帮助

import org.apache.http.entity.mime._
import java.io.File

import org.apache.http.entity.mime.content._
import java.io.ByteArrayOutputStream
import play.api.libs.ws.WS



val contents ="contents string"
val file = File.createTempFile("sample", ".txt")

val bw = new java.io.BufferedWriter(new java.io.FileWriter(file)
bw.write(new_contents);
bw.close();

builder.addPart("file", new FileBody(file, org.apache.http.entity.ContentType.create("text/plain"), "sample"))
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
val entity = builder.build

        val outputstream = new ByteArrayOutputStream
        entity.writeTo(outputstream)
        val header = (entity.getContentType.getName -> entity.getContentType.getValue)
        val response = WS.url("/post/file").withHeaders(header).post(outputstream.toByteArray())

要传递您的内容,取决于客户端,您可以在客户端将内容编码为Base64,以将内容作为Json传递(可以使用Json主体解析器)。 然后在服务器端,您可以使用Base64解码器(例如Apache Commons)对内容进行解码以获得字节数组。 就像

Base64.decodeBase64(YourEncodedFileContent)

当您拥有字节数组时,您可以简单地将其写入磁盘或将其保存到数据库等中。我们在生产中使用了这种方法,它可以正常工作,但是我们仅处理小文件上传。

好的,谢谢大家的建议...以下是我解决问题的方法:

object Files extends Controller {

  def upload = SecuredAction[Files.type]("upload").async(parse.multipartFormData(partHandler)) { implicit request =>
    future { request.body.files.head.ref match {
      case Some((data, fileName, contentType)) => Ok(success(Json.obj("fileName" -> fileName)))
      case _ => BadRequest
    }}.recover { case e =>
     InternalServerError(error(errorProcessingRequest(e.getMessage)))
    }
  }

  ...

  private def partHandler = {
    parse.Multipart.handleFilePart {
      case parse.Multipart.FileInfo(partName, fileName, contentType) =>
        Iteratee.fold[Array[Byte], ByteArrayOutputStream](
          new ByteArrayOutputStream
        ) { (outputStream, data) =>
          outputStream.write(data)
          outputStream
        }.map { outputStream =>
          outputStream.close()
          Some(outputStream.toByteArray, fileName, contentType.get)
        }
    }
  }
}

希望对您有所帮助。

虽然我的后端不提供任何形式...它仅包含要由JavaScript客户端调用的REST API

那么您的后端不是REST API。 您应遵循HATEOAS原则,因此应使用链接和表格以及与每个GET请求有关的数据进行响应。 您不必发回HTML,您可以使用超媒体json或xml媒体类型来描述这些内容,例如JSON-LD,HAL + JSON,ATOM + XML等。因此,您必须描述您的上传表单在您首选的超媒体中,然后让REST客户端将该描述转换为真实的HTML文件上传表单(如果客户端为HTML)。 之后,您可以照常发送multipart/form-data (REST是与媒体类型无关的,因此您可以使用所需的任何媒体类型发送数据,而不仅仅是JSON格式)。 检查AJAX文件上传技术以获取更多详细信息...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM