当前位置: 首页 > 面试题库 >

在Play Framework 2.0中将文件上传为流

艾善
2023-03-14
问题内容

我正在编写一个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();
  }

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

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

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

我到处搜索,没有找到任何解决方案。我发现的最接近的示例是为什么在Play Framework2.0中使调用挂起错误或在BodyParser的Iteratee中完成了请求?但是我没有找到如何修改它以满足我的需求。

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类,其中包含对第三方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的参数,但我无法做到这一点。因此,我添加了一段javascript,它更新了输入字段的名称(并因此更新了partName),并且可以解决问题。



 类似资料:
  • 我知道这是一个非常普遍的问题,但我无法在Angular 2中上传文件。我试过了 1) http://valor-software.com/ng2-file-upload/和 2) http://ng2-uploader.com/home ...但是失败了。有人用Angular上传过文件吗?你用了什么方法?如何做到这一点?如果提供任何示例代码或演示链接,我们将不胜感激。

  • 我看的是: > 与谷歌云平台集成 当前代码:

  • 问题内容: 有很多关于使用go 发布文件的教程,但是几乎总是以这样的方式开始: 也就是说,您将整个文件读入内存,然后将其转换为并将其传递给请求,如下所示: 如果您想发布海量文件并避免将其读取到内存中,而是将文件分块蒸出……您将如何做? 问题答案: 如果需要设置,可以手动完成。以下代码段是将文件和其他参数作为流上传的示例(基于Golang中无缓冲区Multipart POST的代码 )

  • 我正在尝试使用多部分实体方法上传文件。但它失败,错误说{“错误”:“文件参数值'无'无效”} 我的代码是: File File = new File(" C:/Users/SST-06/Desktop/new . txt "); 我的实体文件包含所有提到的参数。 -hkYO-pblk 0 uqlxjtvklrbkosxz 7 mye-8 wbvbvanx Content-Disposition:f

  • 问题内容: 我正在尝试在我的GAE应用程序中上传文件。如何使用Go和使用在Google App Engine中上载文件? 问题答案: 我设法通过使用中间返回参数“其他”解决了我的问题。以下这些代码位于上传处理程序中 然后分配相应的formkey 并在我的结构值分配中像这样使用它 并非100%肯定这是正确的做法,但这解决了我的问题,它现在将图像上传到blobstore,并将其他数据和blobkey保

  • 问题内容: 我已经做了很多研究,找到了.NET的上载组件,可以用来上载大文件,具有进度条并可以继续上载大文件。我遇到了一些组件,例如AjaxUploader,SlickUpload和PowUpload,仅举几例。这些选项中的每一个都需要花钱,只有PowUpload可以执行断点续传,但是它使用Java applet来完成。我愿意为一个能够很好地完成这些工作的组件付费,但是如果我自己编写,那将是最好的