Uploading a File with a Servlet

Since Java EE 6 it is now easier to upload a File without the need of third party API. This can be done by setting the @MultipartConfig annotation within a Servlet. Let’s see a full example starting from an HTML page which contains a form with a “file” type field:

<form action="MyUploadServlet" enctype="multipart/form-data" method="POST">
<input type="file" name="FileName"><br>
<input type="Submit" value="Upload File"><br>
</form>

So far nothing new, now let’s see the MyUploadServlet in action:

@WebServlet("MyUploadServlet")
@MultipartConfig(location="/home/user/uploads")
public class MyUploadServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        for (Part part : request.getParts()) {        
            part.write("filename.dmp");
        }
    }
 
    . . . .
}

As you can see, the Part interface represents a part or form item that was sent within a multipart form-data POST request. The core methods available are getInputStream() and write(String fileName) that we can use to read and write file to the location specified by the location parameter.

Customizing the MultipartConfig configuration

You can supply some additional parameters to the MultipartConfig annotation to specify, besides the location where to write, we can also specify the following ones:

  • fileSizeThreshold: This is the size threshold after which the file will be written to disk. The size value is in bytes.
  • maxFileSize: This is the maximum size (in bytes) allowed to upload a file. Its default value is -1L which means unlimited.
  • maxRequestSize: This is maximum size allowed for multipart/form-data request. The default value is -1L that means unlimited.

@MultipartConfig(location="/tmp", fileSizeThreshold=1024*1024, 
    maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)

    
Instead of using the @MultipartConfig annotation to hard-code these attributes in your file upload servlet, you could also add the following as a child element of the servlet configuration element in the web.xml file.

<multipart-config>
    <location>/tmp</location>
    <max-file-size>20848820</max-file-size>
    <max-request-size>418018841</max-request-size>
    <file-size-threshold>1048576</file-size-threshold>
</multipart-config>

Reading the Uploaded file name information:

If you don’t want to hardcode the file name to be uploaded in your Servlet, then you can access a parameter named “content-disposition” from the HTTP Header which contains the File name for a specific Part object. See the following snippet for an example:

    private String readFileName(Part part) {
        String strContent = part.getHeader("content-disposition");
        String[] tokens = strContent.split(";");
        for (String token : tokens) {
            if (token.trim().startsWith("filename")) {
                return token.substring(token.indexOf("=") + 2, token.length()-1);
            }
        }
        return "";
    }