播放:如何在上传后第一次请求时阻止图片src上的404

时间:2016-09-10 11:23:41

标签: java playframework image-upload playframework-2.5

我有一个包含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次重新加载。

所以它的定义只是一个时间问题,但让线程睡眠任意数量都是错误的。 必须有一种方法可以确保该文件在类路径中可用。

赞赏每一个提示/想法。

1 个答案:

答案 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">

可以在重定向请求中立即访问图像。

我猜测问题的延迟是,该游戏尝试编译添加到类路径中的所有内容,然后才能访问它