无法使用播放框架 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.png
和 2.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 它们。因此,有一个应用程序外部的目录来存储上传的文件。
目标是能够下载和渲染(例如个人资料图片)图像,这些图像要么是 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.png
和 2.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 它们。因此,有一个应用程序外部的目录来存储上传的文件。