Spring MVC File Upload with CommonsMultipartResolver

Learn to use Apache Commons’ CommonsMultipartResolver class to add the file upload feature in a Spring MVC application.

1. Maven Dependencies

Add the latest versions of the commons-fileupload and commons-io modules in the application. The Commons FileUpload package makes it easy to create robust, high-performance, file upload capability in a web application.

This module checks if an HTTP request is submitted using the POST method, and with a content type of “multipart/form-data“, then it can parse the request and process it.

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

2. Spring MVC MultipartFile Interface

A file uploaded to a Spring MVC application will be wrapped in a MultipartFile object. All we need to do is to write a domain class with a property of type MultipartFile.

The MultipartFile interface has methods for getting the name and content of an uploaded file e.g. getBytes(), getInputStream(), getOriginalFilename(), getSize(), isEmpty() and tranferTo().

For example, to save the uploaded file to the filesystem, we can use the transferTo() method:

File file = new File(...);
multipartFile.transferTo(file);

3. Domain Class

We need to create a simple domain class with necessary attributes and one for storing files of type MultipartFile or List<MultipartFile> (if multiple file uploads are needed).

To build this example, I have written this domain class.

public class Product implements Serializable 
{
    private static final long serialVersionUID = 74458L;
 
    @NotNull
    @Size(min=1, max=10)
    private String name;
 
    private String description;
 
    private List<MultipartFile> images;
     
  //getters and setters
}

4. MVC Controller

In the controller class, we will get pre-populated details of uploaded files in the Product class. Just fetch the details and store the files in a file system or database as per application design.

@Controller
public class DemoProductController 
{
  @RequestMapping("/save-product")
  public String uploadResources( HttpServletRequest servletRequest, 
                 @ModelAttribute Product product,
                 Model model) 
  {
    //Get the uploaded files and store them
    List<MultipartFile> files = product.getImages();
        List<String> fileNames = new ArrayList<String>();
        if (null != files && files.size() > 0) 
        {
            for (MultipartFile multipartFile : files) {
 
                String fileName = multipartFile.getOriginalFilename();
                fileNames.add(fileName);
 
                File imageFile = new File(servletRequest.getServletContext().getRealPath("/image"), fileName);
                try
                {
                    multipartFile.transferTo(imageFile);
                } catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }
        }
 
        // Here, you can save the product details in database
         
        model.addAttribute("product", product);
        return "viewProductDetail";
  }
   
  @RequestMapping(value = "/product-input-form")
    public String inputProduct(Model model) {
        model.addAttribute("product", new Product());
        return "productForm";
    }
}

5. File Upload Size and Path Configuration

To support multipart requests, we will need to declare MultipartResolver bean in the configuration file.

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="20848820" />
</bean>

Equivalent Java annotation configuration is :

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() 
{
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(20848820);
    return multipartResolver;
}

Additionally, we may want to map the file storage path on the server as a resource. This will be spring mvc file upload directory.

<mvc:resources mapping="/image/**" location="/image/" /> 

The complete configuration file used for this example is:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context/
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc/
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
  <context:component-scan base-package="com.howtodoinjava.demo" />
   
  <mvc:resources mapping="/image/**" location="/image/" /> 
 
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
   
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
  </bean>
   
  <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
      <property name="basename" value="messages" />
  </bean>
   
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="20848820" />
  </bean>
   
</beans>

6. MVC Views with Upload Form

I have written two JSP files. One for showing the file upload form where user will fill the other details and choose files to upload. Second where we will display the upload files with other details.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<title>Add Product Form</title>
</head>
<body>
  <div id="global">
    <form:form commandName="product" action="save-product" method="post" enctype="multipart/form-data">
      <fieldset>
        <legend>Add a product</legend>
        <p>
          <label for="name">Product Name: </label>
          <form:input id="name" path="name" cssErrorClass="error" />
          <form:errors path="name" cssClass="error" />
        </p>
        <p>
          <label for="description">Description: </label>
          <form:input id="description" path="description" />
        </p>
        <p>
          <label for="image">Product Images: </label> 
          <input type="file" name="images" multiple="multiple"/>
        </p>
        <p id="buttons">
          <input id="reset" type="reset" tabindex="4"> 
          <input id="submit" type="submit" tabindex="5" value="Add Product">
        </p>
      </fieldset>
    </form:form>
  </div>
</body>
</html>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<title>Save Product</title>
</head>
<body>
<div id="global">
    <h4>The product has been saved.</h4>
        <h5>Details:</h5>
        Product Name: ${product.name}<br/>
        Description: ${product.description}<br/>
        <p>Following files are uploaded successfully.</p>
        <ol>
        <c:forEach items="${product.images}" var="image">
            <li>${image.originalFilename}
            <img width="100" src="<c:url value="/image/"/>${image.originalFilename}"/>
            </li>
        </c:forEach>
        </ol>
</div>
</body>
</html>

7. Demo

When we hit the browser with http://localhost:8080/springmvcexample/product-input-form, we get the following screen:

Spring MVC file upload form
Spring MVC file upload form

we fill the details and submit the form and we will get the submitted details and all uploaded files on another page:

file uploaded successfully
file uploaded successfully

Drop me your questions and suggestions in comments section related to this spring MVC multipart file upload example.

Happy Learning !!

Leave a Reply

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.