I have the following basic Action (for illustration purposes) in my controller that is passed a MultipartFormData object and retrieves the image and file name. If not null then prints the file name to the sbt console (witch it does) and then according to play http://www.playframework.com/documentation/2.1.0/JavaFileUpload documentation hopefully save it to the directory specified in file.renameTo (witch is does not).
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();
}
The part that I can't find any documentation on is how you actually move this file in to the public folder of the play project. I noticed the scala guys have the function
ref.moveTo()
I know that there are at least 2 to 3 other questions that are similar but they do not describe how to move the file to a project directory. I'm missing something fundamentally very simple here but I cannot find it documented anywhere on the net.
On further inspection it turns out that play first saves the uploaded image to the system specific temporary directory that in my case was /tmp/
.
My linux system is set up with with three partitions:-
/boot
/
/home
The play installation is located on the /home
partition, logically separated from /
where tmp
resides. In this case the partitions are treated as separate file systems.
javadoc states:-
The rename operation might not be able to move a file from one filesystem to another
Meaning that depending on the system there's a chance that File.renameTo()
may not operate across two different partitions, disks or filesystems. This is the reason that .renameTo()
was failing.
Solution:-
Use apache commons io FileUtils.moveFile()
In Build.scala
add "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"
)
In the play console use play clean compile
.
If using 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();
}
Use relative path instead of absolute (to filesystem)
file.renameTo(new File("public/images/products", fileName));