我的控制器中有以下基本操作(用于说明目的),它传递一个MultipartFormData对象并检索图像和文件名。如果不为null则将文件名打印到sbt控制台(它会这样做),然后根据播放http://www.playframework.com/documentation/2.1.0/JavaFileUpload文档,希望将其保存到file.renameTo中指定的目录(女巫不会)。
public static Result uploadProductImage(
Http.MultipartFormData body
) {
Http.MultipartFormData.FilePart image = body.getFile("image");
if (image != null) {
String fileName = image.getFilename();
System.out.println(fileName);
File file = image.getFile();
file.renameTo(new File("/public/images/products", fileName));
}
return products();
}
我找不到任何文档的部分是你如何将这个文件实际移动到play项目的公共文件夹中。我注意到scala人有这个功能
ref.moveTo()
我知道至少有2到3个其他类似的问题,但它们没有描述如何将文件移动到项目目录。我在这里遗漏了一些非常简单的东西,但我无法在网上的任何地方找到它。
答案 0 :(得分:7)
进一步检查后发现,播放首先将上传的图像保存到系统特定的临时目录,在我的情况下是/tmp/
。
我的linux系统设置有三个分区: -
/boot
/
/home
播放安装位于/home
分区上,逻辑上与/
所在的tmp
分开。在这种情况下,分区被视为单独的文件系统。
javadoc声明: -
重命名操作可能无法将文件从一个文件系统移动到另一个文件系统
这意味着根据系统的不同,File.renameTo()
可能无法跨两个不同的分区,磁盘或文件系统运行。这就是.renameTo()
失败的原因。
解决方案: -
使用apache commons io FileUtils.moveFile()
在Build.scala
添加"org.apache.directory.studio" % "org.apache.commons.io" % "2.4"
val appDependencies = Seq(
javaCore, jdbc, javaJdbc, javaEbean,
"org.apache.directory.studio" % "org.apache.commons.io" % "2.4"
)
在播放控制台中使用play clean compile
。
如果使用IDEA play idea
public static Result uploadProductImage(
Http.MultipartFormData body
) {
Http.MultipartFormData.FilePart image = body.getFile("image");
if (image != null) {
String fileName = image.getFilename();
File file = image.getFile();
try {
FileUtils.moveFile(file, new File("public/images/products", fileName));
} catch (IOException ioe) {
System.out.println("Problem operating on filesystem");
}
}
return products();
}
答案 1 :(得分:1)
使用相对路径而不是绝对路径(到文件系统)
file.renameTo(new File("public/images/products", fileName));