java 如何使用 Commons FileUpload 设置用于存储文件上传的文件夹

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13528081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:06:11  来源:igfitidea点击:

How do I set the folder for storing file uploads using Commons FileUpload

javaservletsfile-uploadapache-commons-fileupload

提问by jazibobs

How do I set to location of where to store file uploads on a TOMCAT server?

如何设置在 TOMCAT 服务器上存储文件上传的位置?

I am using commons.fileuploadand as it stands I am able to store multiple .tmpfiles to catalina_base/temphowever, my aim is to store the uploaded folders in their original form to d:\\dev\\uploadservlet\\web\\uploads

我正在使用commons.fileupload并且目前我能够将多个.tmp文件存储到catalina_base/temp但是,我的目标是将上传的文件夹以其原始形式存储到d:\\dev\\uploadservlet\\web\\uploads

I know this question is vague but to be honest I've been working with servlets for such a short amount of time and I don't yet understand the big picture, any suggestions of code or links to tutorials would be greatly appreciated.

我知道这个问题很模糊,但老实说,我使用 servlet 的时间很短,我还不了解大局,任何代码建议或教程链接都将不胜感激。

My servlet code which handles the uploads is as follows:

我处理上传的 servlet 代码如下:

package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class TestServlet extends HttpServlet {

private static final long serialVersionUID = 1L;    
    public static final long MAX_UPLOAD_IN_MEGS = 5;

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

            //This is the folder I want to use!!
            //String uploadFolder = "d:\dev\uploadservlet\web\uploads";

    boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
    if (!isMultipartContent) {
        out.println("Upload unsuccessful<br/>");
        return;
    }

    out.println("The following was uploaded:<br/>");

    FileItemFactory factory = new DiskFileItemFactory();     
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setSizeMax(MAX_UPLOAD_IN_MEGS * 1024 * 1024);


    TestProgressListener testProgressListener = new TestProgressListener();
    upload.setProgressListener(testProgressListener);

    HttpSession session = request.getSession();
    session.setAttribute("testProgressListener", testProgressListener);

    try {
        List<FileItem> fields = upload.parseRequest(request);
        out.println("Number of fields: " + fields.size() + "<br/><br/>");
        Iterator<FileItem> it = fields.iterator();
        if (!it.hasNext()) {
            out.println("No fields found");
            return;
        }
        out.println("<table border=\"1\">");
        while (it.hasNext()) {
            out.println("<tr>");
            FileItem fileItem = it.next();
            boolean isFormField = fileItem.isFormField();
            if (isFormField) {
                out.println("<td>regular form field</td><td>FIELD NAME: " + fileItem.getFieldName() + 
                        "<br/>STRING: " + fileItem.getString()
                        );
                out.println("</td>");
            } else {
                out.println("<td>file form field</td><td>FIELDNAME: " + fileItem.getFieldName() +//                     <br/>STRING: " + fileItem.getString() +
                        "<br/>NAME: " + fileItem.getName() +
                        "<br/>CONTENT TYPE: " + fileItem.getContentType() +
                        "<br/>SIZE (BYTES): " + fileItem.getSize() +
                        "<br/>TO STRING: " + fileItem.toString()
                        );
                out.println("</td>");
            }
            out.println("</tr>");
        }
        out.println("</table>");
    } catch (FileUploadException e) {
        out.println("Error: " + e.getMessage());
        e.printStackTrace();
    }
}
}

...and it get's it's information from this HTML form:

...它从这个 HTML 表单中获取信息:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Upload Page</title>


    <link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.24.custom.css">
    <link rel="stylesheet" type="text/css" href="css/style.css"

    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/jquery-ui.js"></script>
    <script type="text/javascript" src="uploadFunctions.js"></script>

</head>

<body>
    <div>
        <form name="uploadForm" id="uploadForm" action="test" method="post" enctype="multipart/form-data">
            <input type="hidden" name="hiddenfield1" value="ok">
            <h3>Files to upload:</h3>
            <input type="file" size="50" name="file1">
            <span id="file1Progress">-</span>
            <br/>
            <a href="javascript:previewFile(1)">Preview</a>
            <br/>
            <br/>

            <input type="file" size="50" name="file2">
            <span id="file2Progress">-</span>
            <br/>
            <a href="javascript:previewFile(2)">Preview</a>
            <br/>
            <br/>

            <input type="file" size="50" name="file3">
            <span id="file3Progress">-</span>
            <br/>
            <a href="javascript:previewFile(3)">Preview</a>
            <br/>
            <br/>

            <input type="file" size="50" name="file4">
            <span id="file4Progress">-</span>
            <br/>
            <a href="javascript:previewFile(4)">Preview</a>
            <br/>
            <br/>

            <input type="file" size="50" name="file5">
            <span id="file5Progress">-</span>
            <br/>
            <a href="javascript:previewFile(5)">Preview</a>
            <br/>
            <br/>
            <input type="button" value="Upload" id="submitButton" onclick="uploadForm.submit();doProgress();">
            <br/>
            <br/>
        </form>

        <div class="progBar">                
            File number: <span id="fileText">-</span> is being uploaded.<br/> 
            <br/>
            <progress id="progressBar" value="0" max="100"></progress><br/>
            Upload of all files is: <span id="progressText">-</span>% complete.<br/>
        </div>
    </div>
</body>
</html>

采纳答案by BalusC

Just pass the desired location into FileItem#write()method the usual way as described in the Apache Commons FileUpload's own users guide.

只需FileItem#write()按照 Apache Commons FileUpload's own users guide 中所述的常用方式将所需位置传递到方法中。

First initialize the upload folder in the init()of your servlet.

首先初始化init()servlet 中的上传文件夹。

private File uploadFolder;

@Override
public void init() throws ServletException {
    uploadFolder = new File("D:\dev\uploadservlet\web\uploads");
}

(you can if necessary get this information from an environment variable or a properties file)

(如有必要,您可以从环境变量或属性文件中获取此信息)

Then extract the base name and extension from the filename of the uploaded file and generate an unique filename based on it (you of course don't want that a previously uploaded file get overwritten when someone else by coincidence uploads a file with the same name, right?):

然后从上传文件的文件名中提取基本名称和扩展名,并基于它生成一个唯一的文件名(您当然不希望以前上传的文件在其他人巧合上传具有相同名称的文件时被覆盖,对?):

String fileName = FilenameUtils.getName(fileItem.getName());
String fileNamePrefix = FilenameUtils.getBaseName(fileName) + "_";
String fileNameSuffix = "." + FilenameUtils.getExtension(fileName);
File file = File.createTempFile(fileNamePrefix, fileNameSuffix, uploadFolder);
fileItem.write(file);
System.out.println("File successfully saved as " + file.getAbsolutePath());
// ...

(note that the File#createTempFile()doesn't necessarily mean that it's a temporary file which will be auto-deleted at some time, no, it's in this particular case just been used as a tool in order to generate a file with a guaranteed unique filename in the given folder)

(请注意,这File#createTempFile()并不一定意味着它是一个临时文件,它会在某个时候被自动删除,不,在这种特殊情况下,它只是被用作一种工具,以便生成具有保证唯一文件名的文件给定文件夹)

The FilenameUtilsis provided by Apache Commons IO which you should already have installed as it's a dependency of Commons FileUpload.

FilenameUtils由你应该已经安装,因为它是通用FileUpload的依赖关系的Apache下议院IO提供。



Note that you should absolutely not set it as 2nd argument of DiskFileItemFactoryconstructor as suggested by the other answer. This represents, as clearly mentioned in its javadoc, the temporary disk file system location to store uploaded files when they exceed the threshold size (i.e. when they become too large to hold entirely in server's memory). This location is absolutely not intented as a permanent storage location for uploaded files. It will be auto-cleaned up at intervals by Commons FileUpload.

请注意,您绝对不应DiskFileItemFactory按照其他答案的建议将其设置为构造函数的第二个参数。这表示,正如其 javadoc 中明确提到的,当上传的文件超过阈值大小时(即,当它们变得太大而无法完全保存在服务器的内存中时),临时磁盘文件系统位置用于存储上传的文件。此位置绝对不打算作为上传文件的永久存储位置。它将由 Commons FileUpload 每隔一段时间自动清理。

回答by Sergey Vedernikov

Have you seen javadoc of DiskFileItemFactory? There is a method setRepositorywhich takes Fileargument (folder where temp files will be stored).

你看过 javadocDiskFileItemFactory吗?有一种setRepository接受File参数的方法(将存储临时文件的文件夹)。

So try this:

所以试试这个:

    FileItemFactory factory = 
       new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, 
                               new File("d:\dev\uploadservlet\web\uploads"));

And when you parsing form fields, you can save this files wherever you want.

当您解析表单字段时,您可以将这些文件保存在您想要的任何位置。

Hope it will help you.

希望它会帮助你。

回答by BalusC

You are using FileUpload to manage your upload. so In your code, you just define a file and write the data to it. I will copy only the relevant part and add to it :

您正在使用 FileUpload 来管理您的上传。所以在您的代码中,您只需定义一个文件并将数据写入其中。我将只复制相关部分并添加到其中:

if (isFormField) {
                out.println("<td>regular form field</td><td>FIELD NAME: " + fileItem.getFieldName() + 
                        "<br/>STRING: " + fileItem.getString()
                        );
                out.println("</td>");
            } else {

              //write the file
              String myPath= ..... 
              File f=new File(myPath);
              fileItem.write(f); 

                out.println("<td>file form field</td><td>FIELDNAME: " + fileItem.getFieldName() +//                     <br/>STRING: " + fileItem.getString() +
                        "<br/>NAME: " + fileItem.getName() +
                        "<br/>CONTENT TYPE: " + fileItem.getContentType() +
                        "<br/>SIZE (BYTES): " + fileItem.getSize() +
                        "<br/>TO STRING: " + fileItem.toString()
                        );
                out.println("</td>");
            }

IMPORTANT: make sure you have write permission to the folder where you write the file.

重要提示:确保您对写入文件的文件夹具有写入权限。