// Tutorial //

Servlet 3 File Upload - @MultipartConfig, Part

Published on August 3, 2022
Default avatar
By Pankaj
Developer and author at DigitalOcean.
Servlet 3 File Upload - @MultipartConfig, Part

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Today we will look into Servlet 3 File Upload Example using @MultipartConfig annotation and javax.servlet.http.Part. Sometime back I wrote an article about Servlet File Upload and I used Apache FileUpload API but here we will use Servlet 3 File Upload feature.

Servlet 3 File Upload

Since File Upload is a common task in web applications, Servlet Specs 3.0 provided additional support for uploading files to server and we don’t have to depend on any third party APIs for this. In this tutorial we will see how we can use Servlet 3.0 API for uploading Files to server.

MultipartConfig

We need to annotate File Upload handler servlet with MultipartConfig annotation to handle multipart/form-data requests that is used for uploading file to server. MultipartConfig annotation has following attributes:

  • fileSizeThreshold: We can specify the size threshold after which the file will be written to disk. The size value is in bytes, so 1024*1024*10 is 10 MB.
  • location: Directory where files will be stored by default, it’s default value is “”.
  • maxFileSize: Maximum size allowed to upload a file, it’s value is provided in bytes. It’s default value is -1L means unlimited.
  • maxRequestSize: Maximum size allowed for multipart/form-data request. Default value is -1L that means unlimited.

Read more about annotations at Java Annotations Tutorial.

Part Interface

Part interface represents a part or form item that was received within a multipart/form-data POST request. Some important methods are getInputStream(), write(String fileName) that we can use to read and write file.

HttpServletRequest Changes

New methods got added in HttpServletRequest to get all the parts in multipart/form-data request through getParts() method. We can get a specific part using getPart(String partName) method. Let’s see a simple project where we will use above API methods to upload file using servlet. Our project structure will look like below image. Servlet 3 File Upload, @MultipartConfig, javax.servlet.http.Part

HTML Form

We have a simple html page where we can select the file to upload and submit request to server to get it uploaded. index.html

<html>
<head></head>
<body>
<form action="FileUploadServlet" method="post" enctype="multipart/form-data">
Select File to Upload:<input type="file" name="fileName">
<br>
<input type="submit" value="Upload">
</form>
</body>
</html>

File Upload Servlet

Here is our File Upload Servlet implementation. FileUploadServlet.java

package com.journaldev.servlet;
 
import java.io.File;
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
 
@WebServlet("/FileUploadServlet")
@MultipartConfig(fileSizeThreshold=1024*1024*10, 	// 10 MB 
                 maxFileSize=1024*1024*50,      	// 50 MB
                 maxRequestSize=1024*1024*100)   	// 100 MB
public class FileUploadServlet extends HttpServlet {
 
    private static final long serialVersionUID = 205242440643911308L;
	
    /**
     * Directory where uploaded files will be saved, its relative to
     * the web application directory.
     */
    private static final String UPLOAD_DIR = "uploads";
     
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // gets absolute path of the web application
        String applicationPath = request.getServletContext().getRealPath("");
        // constructs path of the directory to save uploaded file
        String uploadFilePath = applicationPath + File.separator + UPLOAD_DIR;
         
        // creates the save directory if it does not exists
        File fileSaveDir = new File(uploadFilePath);
        if (!fileSaveDir.exists()) {
            fileSaveDir.mkdirs();
        }
        System.out.println("Upload File Directory="+fileSaveDir.getAbsolutePath());
        
        String fileName = null;
        //Get all the parts from request and write it to the file on server
        for (Part part : request.getParts()) {
            fileName = getFileName(part);
            part.write(uploadFilePath + File.separator + fileName);
        }
 
        request.setAttribute("message", fileName + " File uploaded successfully!");
        getServletContext().getRequestDispatcher("/response.jsp").forward(
                request, response);
    }
 
    /**
     * Utility method to get file name from HTTP header content-disposition
     */
    private String getFileName(Part part) {
        String contentDisp = part.getHeader("content-disposition");
        System.out.println("content-disposition header= "+contentDisp);
        String[] tokens = contentDisp.split(";");
        for (String token : tokens) {
            if (token.trim().startsWith("filename")) {
                return token.substring(token.indexOf("=") + 2, token.length()-1);
            }
        }
        return "";
    }
}

Notice the use of @MultipartConfig annotation to specify different size parameters for upload file. We need to use request header “content-disposition” attribute to get the file name sent by client, we will save the file with same name. The directory location is relative to web application where I am saving the file, you can configure it to some other location like in Apache Commons FileUpload example.

Response JSP

A simple JSP page that will be sent as response to client once the file is uploaded successfully to server. response.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Upload File Response</title>
</head>
<body>
	<%-- Using JSP EL to get message attribute value from request scope --%>
    <h2>${requestScope.message}</h2>
</body>
</html>

Deployment Descriptor

There is nothing new in web.xml file for servlet file upload, it’s only used to make the index.html as welcome file. web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>ServletFileUploadExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

Now when we run the application, we get following pages as response. Servlet 3 File Upload HTML Servlet 3 File Upload Success The logs will show the directory location where file is saved and content-disposition header information.

Upload File Directory=/Users/pankaj/Documents/workspace/j2ee/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ServletFileUploadExample/uploads
content-disposition header= form-data; name="fileName"; filename="IMG_2046.jpg"

I am running Tomcat through Eclipse, that’s why file location is like this. If you run tomcat through command line and deploy application by exporting as WAR file into webapps directory, you will get different structure but a clear one.

Download Servlet 3 Multipart File Upload Project


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Pankaj

author

Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

It Says “Cannot call sendRedirect() after the response has been committed” why is it happen sir

- Chamindu

    This code work with other parameters but gives IOException at server side. Refer to my answer to get problem. https://stackoverflow.com/questions/50857699/java-io-filenotfoundexception-c-users-user-appdata-local-temp-access-is-denie/56805663#56805663

    - Navneet

      It works so well. But when i try to upload large no of files ( size above @multipart fileSizeThreshold size) , it has be stored in a tmp dir. But it doesnt… And I’m getting this exception. Can anyone please say what can be done. work\Catalina\localhost\FileUpload\upload_92818694_fdfa_426f_9c9f_43321e273e2e_00000426.tmp file not found. Thanks in advance.

      - Jane

        Hello, Pankaj.Following error is shown when I try to run this project. I have created a folder with the same name “uploads” under WebContent. Please help. HTTP Status 404 - /Upload_demo_Project/response.jsp type Status report message /Upload_demo_Project/response.jsp description The requested resource is not available.

        - harkirat

          Hi, when I make getParts() I just get an empty list. Why? I see the correct payload of my POST request like this: ------WebKitFormBoundaryh09EyJNK015Dn2QF Content-Disposition: form-data; name=“usecase” 1 ------WebKitFormBoundaryh09EyJNK015Dn2QF Content-Disposition: form-data; name=“file”; filename=“301__Ferrari__308 Gruppe 4__1980__.jpg” Content-Type: image/jpeg ------WebKitFormBoundaryh09EyJNK015Dn2QF Content-Disposition: form-data; name=“file”; filename=“302__Porsche__906__1966__.jpg” Content-Type: image/jpeg ------WebKitFormBoundaryh09EyJNK015Dn2QF–

          - bzmichi

            HTTP Status 500 - type Exception report message descriptionThe server encountered an internal error () that prevented it from fulfilling this request. exception java.io.FileNotFoundException: \D:\OnlineShoppingCenter-20170131T093840Z\OnlineShoppingCenter\build\web\productImages\cranberry-cheesecake-ck-x.jpg (The filename, directory name, or volume label syntax is incorrect) note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.0.1 logs. GlassFish Server Open Source Edition 3.0.1 UploadFile.java import java.io.File; import java.io.IOException; //import java.io.*; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; @WebServlet(“/UploadFile”) @MultipartConfig(fileSizeThreshold=1024*1024*2, // 2MB maxFileSize=1024*1024*10, // 10MB maxRequestSize=1024*1024*50, location=“/”) // 50MB public class UploadFile extends HttpServlet { /** * Name of the directory where uploaded files will be saved, relative to * the web application directory. */ private static final String SAVE_DIR = “uploadFiles”; /** * handles file upload */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // gets absolute path of the web application String appPath = request.getServletContext().getRealPath(“”); // constructs path of the directory to save uploaded file String savePath = appPath + File.separator + SAVE_DIR; // creates the save directory if it does not exists File fileSaveDir = new File(savePath); if (!fileSaveDir.exists()) { fileSaveDir.mkdir(); } String fileName = null; for (Part part : request.getParts()) { fileName = extractFileName(part); // fileName = " “; File f = new File(fileName); part.write(savePath + File.separator + f.getName()); } request.setAttribute(“message”, fileName + “Upload has been done successfully!”); getServletContext().getRequestDispatcher(”/report-product.jsp").forward( request, response); } /** * Extracts file name from HTTP header content-disposition */ private String extractFileName(Part part) { String contentDisp = part.getHeader(“content-disposition”); String[] items = contentDisp.split(“;”); for (String s : items) { if (s.trim().startsWith(“fileName”)) { return s.substring(s.indexOf(“=”) + 2, s.length()-1); } } return “”; } } UploadProduct.java package pkg; import java.io.File; import java.io.IOException; import Model.*; import java.util.*; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; @WebServlet(“/UploadProduct”) @MultipartConfig(fileSizeThreshold=1024*1024*10, // 10 MB maxFileSize=1024*1024*50, // 50 MB maxRequestSize=1024*1024*100,location=“/” // 100 MB ) // 50MB public class UploadProduct extends HttpServlet { private static final String SAVE_DIR = “productImages”; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //// Logic for Upload the File //// String appPath = request.getServletContext().getRealPath(“”); String savePath = appPath + File.separator + SAVE_DIR; File fileSaveDir = new File(savePath); if (!fileSaveDir.exists()) { fileSaveDir.mkdir(); } long unixTime = System.currentTimeMillis() / 1000L; Part part; part = request.getPart(“product_image”); String fileName = extractFileName(part); if(!fileName.equals(“”)) { fileName = extractFileName(part); File f = new File(fileName); part.write(savePath + File.separator + f.getName()); //part.write(savePath + File.separator + fileName); } else { fileName = request.getParameter(“image_name”); } //// Upload File Complete/// /////Save the Product Details ///// Product productObj = new Product(); String emp_id = “0”; if((request.getParameter(“act”)).equals(“Save”)) { HashMap results = new HashMap(); //results.put(“product_id”,request.getParameter(“product_id”)); results.put(“product_name”,request.getParameter(“product_name”)); results.put(“product_type_id”,request.getParameter(“product_type_id”)); results.put(“product_company_id”,request.getParameter(“product_company_id”)); results.put(“product_description”,request.getParameter(“product_description”)); results.put(“product_price”,request.getParameter(“product_price”)); results.put(“product_id”,request.getParameter(“product_id”)); results.put(“product_stock”,request.getParameter(“product_stock”)); results.put(“product_image”,fileName); if((request.getParameter(“product_id”)).equals(" “)) { productObj.saveProduct(results); request.setAttribute(“message”, “Product Saved Successfully !!!”); getServletContext().getRequestDispatcher(”/report-product.jsp").forward(request, response); } else { results.put(“product_id”,request.getParameter(“product_id”)); productObj.updateProduct(results); request.setAttribute(“message”, “Product Updated Successfully !!!”); getServletContext().getRequestDispatcher(“/report-product.jsp”).forward(request, response); } } } /** * Extracts file name from HTTP header content-disposition */ private String extractFileName(Part part) { String contentDisp = part.getHeader(“content-disposition”); String[] items = contentDisp.split(“;”); for (String s : items) { if (s.trim().startsWith(“filName”)) { return s.substring(s.indexOf(“=”) + 2, s.length()-1); } } return “”; } } Please help me fix this error…!!!

            - Rajitha

              Hey How to solve the FileNotFound Exception

              - Keyur

                type Exception report message java.io.FileNotFoundException: C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ShopNow\images (Access is denied) description The server encountered an internal error that prevented it from fulfilling this request. exception java.io.IOException: java.io.FileNotFoundException: C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ShopNow\images (Access is denied) org.mz.shopnow.controller.admin.AddProductServlet.doPost(AddProductServlet.java:81) javax.servlet.http.HttpServlet.service(HttpServlet.java:647) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) root cause java.io.FileNotFoundException: C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ShopNow\images (Access is denied) java.io.FileOutputStream.open(Native Method) java.io.FileOutputStream.(Unknown Source) java.io.FileOutputStream.(Unknown Source) org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:391) org.mz.shopnow.controller.admin.AddProductServlet.doPost(AddProductServlet.java:81) javax.servlet.http.HttpServlet.service(HttpServlet.java:647) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) note The full stack trace of the root cause is available in the Apache Tomcat/7.0.42 logs. Apache Tomcat/7.0.42

                - ravinder singh

                  HTTP Status 500 - GET method used with upload.UploadServlet: POST method required. type Exception report message GET method used with upload.UploadServlet: POST method required. description The server encountered an internal error that prevented it from fulfilling this request. exception javax.servlet.ServletException: GET method used with upload.UploadServlet: POST method required. upload.UploadServlet.doGet(UploadServlet.java:108) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) note The full stack trace of the root cause is available in the Apache Tomcat/7.0.37 logs.

                  - mansi

                    Hi i am getting below error when i am trying to upload the file java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getPart(Ljava/lang/String;)Ljavax/servlet/http/Part; com.controller.FileUploadDBServlet.doPost(FileUploadDBServlet.java:54) javax.servlet.http.HttpServlet.service(HttpServlet.java:647) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) Can anyone help me on this please

                    - Karthik UL