Play! 2.1 Java complete basic file upload solution

2019-04-14 04:55发布

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.

2条回答
你好瞎i
2楼-- · 2019-04-14 05:53

Use relative path instead of absolute (to filesystem)

file.renameTo(new File("public/images/products", fileName));
查看更多
Emotional °昔
3楼-- · 2019-04-14 05:54

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();
}
查看更多
登录 后发表回答