我试图允许用户将照片上传到服务器,然后在生产(非开发)中查看它们(所有用户都可以查看所有照片)。在开发模式中,一切都很简单 - 我可以将文件上传到公共文件夹,然后从那里读取,在生产模式我无法访问公共文件夹了(因为这种方法适用于静态访问而非动态)。
所以,我有两个问题:
以下是上传代码(与本指南类似 - https://www.playframework.com/documentation/2.4.x/ScalaFileUpload):
def uploadPhoto = Action(parse.multipartFormData) { request =>
import play.api.mvc.MultipartFormData
import play.api.libs.Files.TemporaryFile
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
try {
val multipartForm: MultipartFormData[TemporaryFile] = request.body
val pathDev: Path = Paths.get("./public/img");
val pathProduction: Path = Paths.get("/...<[full path]>.../public/img");
val imgPath =
if (Files.exists(pathDev)) { pathDev.toString() }
else { pathProduction.toString() }
val newFile = img.get.ref.moveTo(new File(s"$imgPath/$imgName"))
// [HERE I save the path to my DB]
Ok(Json.obj("imgName" -> imgName))
} catch {
case e: Exception =>
BadRequest("unknown error")
}
}
但由于公共文件夹不可用,图像是&#34;不存在&#34; (至少直到我将&#34;阶段&#34;项目并重新运行它 - https://www.playframework.com/documentation/2.4.x/Assets)。
我尝试了以下方法(https://www.playframework.com/documentation/2.4.x/ScalaStream): 我已将以下行添加到我的conf / routes文件中: GET / img /:filename controllers.MyController.getPhoto(filename)
并在控制器中定义了以下函数: def getPhoto(filename:String)= Action { Ok.sendFile(新的java.io.File(&#34; ./ img /&#34; + filename)) }
但是浏览器正在下载文件而不是显示它......
这些是相关的: Handling dynamic created files in play 2 How to serve uploaded files in Play!2 using Scala?
任何援助都将被非常挪用。
答案 0 :(得分:2)
以下是我如何解决此问题
问题1
对于上传文件路径,在游戏中你可以在conf / application.conf文件中定义配置,你可以使用不同的文件进行生产模式,使用-Dconfig.file = / path / to / the / file。
所以我定义了一个名为myapp.image.base的属性,在调试模式下只需将其设置为&#34;&#34;,并在生产模式下(我创建了一个名为conf / application.prod.conf的文件),我把它放在绝对的路径上。 所以在我的代码中,我总是使用以下命令来获取文件路径(它在Java中,但你应该在Scala中找到类似的方式来读取配置)
Play.application().configuration().getString("myapp.image.base")+"img"
问题2
用于提供图像 您需要创建一个路由器。 首先在路线文件中添加如下内容:
GET /user/images/:name controllers.Application.imageAt(name:String)
在动作imageAt中编写一个简单的文件阅读器,它以流的形式返回文件。我的示例再次使用Java,但您应该使用Scala将其存档
File imageFile = new File(ReportFileHelper.getImagePath());
if (imageFile.exists()) {
//resource type such as image+png, image+jpg
String resourceType = "image+"+imageName.substring(imageName.length()-3);
return ok(new FileInputStream(imageFile)).as(resourceType);
} else {
return notFound(imageFile.getAbsoluteFile());
}
之后,可以从url / user / images /
访问图像答案 1 :(得分:1)
Play从类路径(包括assets目录)中读取文件。在JVM上,类路径是不可变的 - 一旦启动,添加到类路径上的文件夹的文件实际上不会被添加到类路径中。
这适用于开发模式,因为Play会在检测到更改时重新加载类路径。生产中没有启用相同的热重装(有充分理由)。