我有一个包含2个文本和1个文件输入的简单表单
@helper.form(action = routes.CharactersController.newCharacter(), 'enctype -> "multipart/form-data") {
@helper.inputText(field = characterForm("characterName"))
@helper.inputText(field = characterForm("characterRealName"))
@helper.inputFile(field = characterForm("characterImage"))
<p>
<input type="submit">
</p>
}
在newCharacter操作中,我将文件移动到资产文件夹。
Http.MultipartFormData body = request().body().asMultipartFormData();
Http.MultipartFormData.FilePart<File> picture = body.getFile("characterImage");
File file = picture.getFile();
file.renameTo(new File(LinkUtil.getCharacterUploadPath(), imageName + ".jpg"));
然后重定向到/ show页面以显示新输入的字符
return redirect(routes.CharactersController.show(character.id, OrderType.MAIN.name()));
在新加载的页面上,我只得到一张损坏的图像,并在控制台中查看图像的404。当我重新加载页面时,图像按预期呈现。
当我重定向时,哪个部分还没准备好?是重命名还是玩需要一些时间才能找到新资产? 在重定向之前,如何确保一切准备就绪?
编辑: 改善我的问题
我正在使用play 2.5
LinkUtil.getCharacterUploadPath()解析为&#34; public / images / characters /&#34;
我将图片嵌入到我的演示模板中,如下所示:
<img src="@character.getImagePath">
然后解析为&#34; /assets/images/characters/imagename.jpg"
编辑2:进一步调查:
当我使用类似file.exists()的新路径检查newCharacter操作中的文件系统时,我得到了。所以重命名/移动部分似乎已经完成了。 但是,如果我尝试通过环境获取资源
environment.getResource("relativePathToFile");
它是空的。即使在while循环中,资源也保持为null。这似乎表明该文件尚未真正添加到类路径中。不幸的是,无论我停留多长时间,资源总是为空。但是当我让Thread休眠2000ms然后再在show动作中再次检查资源时,它会得到正确解析。但只有我等了2秒。
另一项测试是使用onerror =&#34; window.location.reload()&#34;在图像上。在找到图像之前,这会导致大约5-10次重新加载。
所以它的定义只是一个时间问题,但让线程睡眠任意数量都是错误的。 必须有一种方法可以确保该文件在类路径中可用。
赞赏每一个提示/想法。
答案 0 :(得分:0)
我得到了它的工作!首先,我的上述方法存在缺陷。
获取上传的图像,将它们放入公共文件夹并尝试使用AssetController提供它们将无法在生产版本中使用。公用文件夹中的所有内容都打包到.jar文件中。一些快速测试暗示我从上面重命名不会将图像放在我预期的位置。
所以这是我的解决方案:
定义新路线:
GET /files/*file controllers.Images.serve(file)
在操作中使用文件系统上的绝对路径
public class Images extends Controller {
public Result serve(String file) {
return ok(new java.io.File("/var/www/files/" + file));
}
}
使用类似的内容访问该文件
<img src="/files/images/characters/imagename.jpg">
可以在重定向请求中立即访问图像。
我猜测问题的延迟是,该游戏尝试编译添加到类路径中的所有内容,然后才能访问它