Saturday, April 18, 2020

Spring MVC Multiple File Upload Example

Spring MVC provides out of box support for multiple file upload functionality in any application. This tutorial uses CommonsMultipartResolver and requires apache commons fileupload and apache commons io dependencies.
pom.xml
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

1. 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. This 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 file system, we can use the transferTo method:
File upload to filesystem
File file = new File(...);
multipartFile.transferTo(file);

2. Domain class for file upload

You need to create a simple domain class with necessary attributes and one for storing files of type List<MultipartFile>.
To build this example, I have written this domain class.
Product.java
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
}

3. Spring MVC multi-file upload controller

In controller class, we will get pre-populated details of uploaded files in domain class. Just fetch the details and store the files in file system or database as per application design.
DemoProductController.java
@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";
    }
}

4. Spring MVC configuration changes

To support multipart request, we will need to declare multipartResolver bean in configuration file.
beans.xml
<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 server as 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.xml
<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>

5. Spring MVC view to upload files

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.
productForm.jsp
<%@ 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>
viewProductDetail.jsp
<%@ 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>

Spring MVC multiple file upload example

When we hit the browser with http://localhost:8080/springmvcexample/product-input-form, we get 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 in other 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.

No comments:

Post a Comment

How to DROP SEQUENCE in Oracle?

  Oracle  DROP SEQUENCE   overview The  DROP SEQUENCE  the statement allows you to remove a sequence from the database. Here is the basic sy...