在play framework 2.0中将文件上传为流

我正在编写一个允许用户上传文件的Play 2.0 java应用程序。 这些文件存储在我使用Java库访问的第三方服务上,我在此API中使用的方法具有以下签名:

void store(InputStream stream, String path, String contentType) 

我已设法使用以下简单的控制器使上传工作:

 public static Result uploadFile(String path) { MultipartFormData body = request().body().asMultipartFormData(); FilePart filePart = body.getFile("files[]"); InputStream is = new FileInputStream(filePart.getFile()) myApi.store(is,path,filePart.getContentType()); return ok(); } 

我担心的是这个解决方案效率不高,因为默认情况下,play框架将客户端上传的所有数据存储在服务器上的临时文件中,然后在控制器中调用uploadFile()方法。

在传统的servlet应用程序中,我会编写一个以这种方式运行的servlet:

 myApi.store(request.getInputStream(), ...) 

我一直在寻找,没有找到任何解决方案。 我找到的最接近的例子是为什么调用错误或在BodyParser的Iteratee中完成请求在Play Framework 2.0中挂起? 但我没有找到如何修改它以满足我的需要。

在play2中是否有一种方法可以实现这种行为,即客户端上传的数据是否可以将Web应用程序直接“传递”到另一个系统?

谢谢。

我已经能够使用以下Scala控制器代码将数据流式传输到我的第三方API:

 def uploadFile() = Action( parse.multipartFormData(myPartHandler) ) { request => Ok("Done") } def myPartHandler: BodyParsers.parse.Multipart.PartHandler[MultipartFormData.FilePart[Result]] = { parse.Multipart.handleFilePart { case parse.Multipart.FileInfo(partName, filename, contentType) => //Still dirty: the path of the file is in the partName... String path = partName; //Set up the PipedOutputStream here, give the input stream to a worker thread val pos:PipedOutputStream = new PipedOutputStream(); val pis:PipedInputStream = new PipedInputStream(pos); val worker:UploadFileWorker = new UploadFileWorker(path,pis); worker.contentType = contentType.get; worker.start(); //Read content to the POS Iteratee.fold[Array[Byte], PipedOutputStream](pos) { (os, data) => os.write(data) os }.mapDone { os => os.close() Ok("upload done") } } } 

UploadFileWorker是一个非常简单的Java类,它包含对thrid-party API的调用。

 public class UploadFileWorker extends Thread { String path; PipedInputStream pis; public String contentType = ""; public UploadFileWorker(String path, PipedInputStream pis) { super(); this.path = path; this.pis = pis; } public void run() { try { myApi.store(pis, path, contentType); pis.close(); } catch (Exception ex) { ex.printStackTrace(); try {pis.close();} catch (Exception ex2) {} } } 

}

它并不完全完美,因为我宁愿将路径恢复为Action的参数,但我无法这样做。 因此,我添加了一段更新输入字段名称(以及partName)的javascript,并且它可以解决问题。