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

17,941

Solution 1

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

First initialize the upload folder in the init() of your 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)

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


Note that you should absolutely not set it as 2nd argument of DiskFileItemFactory constructor 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.

Solution 2

Have you seen javadoc of DiskFileItemFactory? There is a method setRepository which takes File argument (folder where temp files will be stored).

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.

Share:
17,941
jazibobs
Author by

jazibobs

Freelance web developer running things at MTD Digital

Updated on June 26, 2022

Comments

  • jazibobs
    jazibobs almost 2 years

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

    I am using commons.fileupload and as it stands I am able to store multiple .tmp files to catalina_base/temp however, my aim is to store the uploaded folders in their original form to 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.

    My servlet code which handles the uploads is as follows:

    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>
    <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>
    
  • jazibobs
    jazibobs over 11 years
    Thank you Sergey, I can now upload files where I please.
  • Sergey Vedernikov
    Sergey Vedernikov over 11 years
    @jazibobs Do you want to not store .tmp files after uploading? You can use class org.apache.commons.io.FileCleaningTracker.
  • jazibobs
    jazibobs over 11 years
    Thank you again! You've been very helpful :)
  • BalusC
    BalusC over 11 years
    This is not the correct approach. The repository argument represents the local disk file system storage location for uploaded files whose size exceeds the default threshold. This is thus a temporary location and not a permanent location! This location will be cleaned up at intervals.
  • BalusC
    BalusC over 11 years
    Just replace the current catch block by catch (Exception e) { throw new ServletException(e); }