使用 play web api 下载文件(异步)

download a file with play web api (async)

我正在尝试使用播放 api 框架下载文件。因为所有的数据访问层都已经用 Futures 实现了,所以我也想下载以使用异步操作。但是,下面的一段代码不起作用。不工作是指发送到客户端的文件与服务器上的文件不同。

  val sourcePath = "/tmp/sample.pdf"

  def downloadAsync = Action.async {
    Future.successful(Ok.sendFile(new java.io.File(sourcePath)))
  }

然而,这件作品有效:

  def download = Action {
    Ok.sendFile(new java.io.File(sourcePath))
  }

关于如何让异步方法工作有什么建议吗?

你实际上不需要在这里使用 Action.async,因为 Ok.sendFile 已经是非阻塞的了。来自 the docs:

Play actions are asynchronous by default. For instance, in the controller code below, the { Ok(...) } part of the code is not the method body of the controller. It is an anonymous function that is being passed to the Action object’s apply method, which creates an object of type Action. Internally, the anonymous function that you wrote will be called and its result will be enclosed in a Future.

def echo = Action { request =>
  Ok("Got request [" + request + "]")
}

Note: Both Action.apply and Action.async create Action objects that are handled internally in the same way. There is a single kind of Action, which is asynchronous, and not two kinds (a synchronous one and an asynchronous one). The .async builder is just a facility to simplify creating actions based on APIs that return a Future, which makes it easier to write non-blocking code.

换句话说,在这种特定情况下,不必担心将 Result 包装成 Future 而只是 return Ok.sendFile.


最后,两个版本都按我预期的方式运行(文件已正确交付)。也许您有另一个与您声明行为的方式无关的问题。