无法使用播放框架 sendFile 函数定位文件

unable to locate files with play framework sendFile function

目标是能够下载和渲染(例如个人资料图片)图像,这些图像要么是 public 资产,要么是私有图像。

Play Framework docs (ScalaStream) 中,它说:

Play provides easy-to-use helpers for common task of serving a local file:

def index = Action {
  Ok.sendFile(new java.io.File("/tmp/fileToServe.pdf"))
}

If you want to serve this file inline:

def index = Action {
  Ok.sendFile(
    content = new java.io.File("/tmp/fileToServe.pdf"),
    inline = true
  )
}

这看起来像是实现目标所需要的。

现在,我的目录结构如下所示,我想提供文件 1.png2.png

MyApp
|_ app
|_ conf
|_ public (all public assets)
   |_ images
      |_ 1.png
|_ private (more assets, not public)
   |_ images
      |_ 2.png
|_ ...

我定义了一个控制器函数如下:

def sendImage() = Action {
  // Ok.sendFile(new java.io.File("/public/images/1.png"))
  // Ok.sendFile(new java.io.File("assets/images/1.png"))
  Ok.sendFile(new java.io.File("/private/images/1.png"))
}

尝试了各种不同的路径,绝对的,相对的,但是当我从前端(React / Axios)调用这个控制器函数时,它只 returns "NoSuchFileException".

但是,我能够从前端渲染 public 资产,只需使用:

<img src='/assets/images/1.png' />   // from the public dir

同一路径在控制器中不起作用。无法弄清楚 Play 如何期望它的路径。

目前正在使用 Play 2.5

有什么想法吗?谢谢

在您的控制器中注入 play.api.Application 对象并使用应用程序对象中定义的 getFile 方法,如下所示。

class JobInstanceController @Inject()(protected val app: Application) extends Controller {
  def test = Action {
    Ok.sendFile(app.getFile("public/images/1.png"))
  }
}

私有文件夹不在类路径中。我认为您需要将其添加到 build.sbt 文件

unmanagedResourceDirectories in Compile += baseDirectory.value / "private"

看这里 http://www.scala-sbt.org/0.13/docs/Howto-Customizing-Paths.html

@marcospereira 的评论有助于解决问题,谢谢!

当您在文件名前使用 / 时,这需要文件的完整路径而不是相对路径。您需要将 /private/images/1.png 更改为 private/images/1.png 以便它与您的应用程序相关。

但是,如果这些私人文件是由用户上传的,将它们放在应用程序目录中将被认为是一种不好的做法。当您部署新版本的应用程序时会发生什么?您将丢失文件,或者在部署时需要 copy/move 它们。因此,有一个应用程序外部的目录来存储上传的文件。