无法使用播放框架sendFile函数找到文件

时间:2017-02-22 19:16:23

标签: scala playframework playframework-2.5

目标是能够下载和呈现(例如个人资料图片)公共资产或私人资产。

Play Framework docs (ScalaStream)中,它说:

  

Play提供易于使用的帮助程序,用于为本地服务的常见任务   文件:

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

如果您想以内联方式提供此文件:

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)调用这个控制器功能时,它只返回“NoSuchFileException”。

但是,我可以使用以下方式从前端渲染公共资产:

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

相同的路径在控制器内不起作用。无法弄清楚Play如何期待它的路径。

目前正在使用Play 2.5

有什么想法吗?感谢

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

私人文件夹不在类路径中。我认为你需要将它添加到build.sbt文件

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

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

答案 2 :(得分:0)

@marcospereira的评论有助于解决这条道路,谢谢!

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

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