Spring MVC Multiple File Upload Example

This example will show you how to implement multiple file upload and single file upload function in spring mvc. First, let us look at the demo video as below. There are two parts in the page, the top part can upload three files and the bottom part can upload one file. After you upload the file, you can see the uploaded files are saved in server folder /tmp/upload_example.

1. Create Spring MVC Project.

Create a spring mvc project for our upload file example is STS. You can refer Spring MVC Full Java Based Configuration Example to learn how to do it.

create spring mvc multiple file upload project

After create the project, when the example files has been added or edited successfully, you should see the project files as below. This project is a java config annotation based spring project, we will introduce the source files one by one.

spring mvc multiple file upload project source files list

2. Spring Config Java File.

This class is used to configure project used spring beans. The getMultipartFormResolver() method just return CommonsMultipartResolver bean that can resolve file upload issue automatically.

SpringConfig.java

package com.dev2qa.mvc.fileupload.config;

import java.io.IOException;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;

@EnableWebMvc
@Configuration
@ComponentScan(basePackages="com.dev2qa.mvc.fileupload")
public class SpringConfig extends WebMvcConfigurerAdapter {

    public static final String ENCODING_UTF_8 = "UTF-8";

    public static final long MAX_UPLOAD_FILE_SIZE = 52428807;

    public static final long MAX_UPLOAD_PER_FILE_SIZE = 5242880;

    /* CommonsMultipartResolver class provide function that can parse and get the upload file name, data etc. */
    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver getMultipartFormResolver() throws IOException{

        CommonsMultipartResolver ret = new CommonsMultipartResolver();

        ret.setMaxUploadSize(MAX_UPLOAD_FILE_SIZE);

        ret.setMaxUploadSizePerFile(MAX_UPLOAD_PER_FILE_SIZE);

        ret.setDefaultEncoding(ENCODING_UTF_8);

        return ret;
    }

    /* ResourceBundleViewResolver is used to create the returned view object based on the configuration file src/main/resources/config/views.properties. */
    @Bean
    public ResourceBundleViewResolver getBundleViewResolver() {

        ResourceBundleViewResolver ret = new ResourceBundleViewResolver();

        ret.setBasename("config.views");

        ret.setOrder(0);

        return ret;
    }

    /* messageSource method name can not be change to others, else there will has errors when browse web page.
     * MessageSource can help jsp page display the messages defined in the src/main/resources/config/messages_en_US.properties file easily.
     * */
    @Bean(name = "messageSource")
    public MessageSource getMessageSource() {
        ReloadableResourceBundleMessageSource ret = new ReloadableResourceBundleMessageSource();

        ret.setBasename("classpath:config/messages_en_US");

        ret.setCacheSeconds(1);

        ret.setUseCodeAsDefaultMessage(true);

        ret.setDefaultEncoding(ENCODING_UTF_8);

        return ret;
    }
}

3. Spring Dispatcher Servlet Java File.

This class is used to add spring dispatcher servlet and add file upload settings to the servlet.

SpringDispatcherServlet.java

package com.dev2qa.mvc.fileupload.config;

import javax.servlet.FilterRegistration;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.multipart.support.MultipartFilter;
import org.springframework.web.servlet.DispatcherServlet;

@Configuration
public class SpringDispatcherServlet implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();

        dispatcherServletContext.register(SpringConfig.class);

        DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherServletContext);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("file-upload", dispatcherServlet);
         
        /* If do not set multipartconfig in servlet 3, when you upload a file, it will throw Unable to process parts as no multi-part configuration has been provided error. */
        MultipartConfigElement multipartConfig = new MultipartConfigElement("/tmp");
        dispatcher.setMultipartConfig(multipartConfig);

        dispatcher.setLoadOnStartup(1);

        dispatcher.addMapping("*.html");

        FilterRegistration.Dynamic multipartFilter = servletContext.addFilter("multipartFilter", MultipartFilter.class);

        multipartFilter.addMappingForUrlPatterns(null, true, "/*");
    }

}

4. Upload File Controller Java File.

This class is the spring mvc controller class that will process file upload action. It contains two method, one is used to process multiple file upload the other is used to process single file upload.

UploadFileController.java

package com.dev2qa.mvc.fileupload.controller;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.dev2qa.mvc.fileupload.model.FileUploadFormData;

@Controller
@RequestMapping("/upload_file")
public class UploadFileController {
    // This is the server side upload file save folder, make sure the folder exist before run the upload file example.
    private static final String UPLOAD_FILE_SAVE_FOLDER = "/tmp/upload_example/";

    /* This method will display the upload file form page. */
    @RequestMapping(value="/show_upload_file_form.html", method= {RequestMethod.GET, RequestMethod.POST})
    public String uploadFileGetForm(Model model) {

        FileUploadFormData fileUploadFormData = new FileUploadFormData();

        model.addAttribute("fileUploadFormData", fileUploadFormData);

        // Return the upload file form page.
        return "upload_file_show_form";
    }

    /* This method will display a page that contains a link and a button which will link to the upload file form page. */
    @RequestMapping(value="/main.html", method= {RequestMethod.GET, RequestMethod.POST})
    public String displayMainPage(Model model) {

        return "upload_file_main";
    }


    /* Process multiple file upload action and return a result page to user. */
    @RequestMapping(value="/upload_multiple_file.html", method={RequestMethod.PUT, RequestMethod.POST})
    public String uploadFileSubmit(Model model, MultipartHttpServletRequest multipartRequest) {
        try
        {
            StringBuffer msgBuf = new StringBuffer();

            // Get multiple file control names.
            Iterator<String> it = multipartRequest.getFileNames();

            while(it.hasNext())
            {
                String fileControlName = it.next();

                MultipartFile srcFile = multipartRequest.getFile(fileControlName);

                String uploadFileName = srcFile.getOriginalFilename();

                // Create server side target file path.
                String destFilePath = UPLOAD_FILE_SAVE_FOLDER+uploadFileName;

                File destFile = new File(destFilePath);

                // Save uploaded file to target.
                srcFile.transferTo(destFile);

                msgBuf.append("Upload file " + uploadFileName + " is saved to " + destFilePath + "<br/><br/>");
            }

            // Set message that will be displayed in return page.
            model.addAttribute("message", msgBuf.toString());

        }catch(IOException ex)
        {
            ex.printStackTrace();
        }finally
        {
            return "upload_file_result";
        }
    }


    /* Process one file upload action and return a result page to user. */
    @RequestMapping(value="/upload_one_file.html", method={RequestMethod.PUT, RequestMethod.POST})
    public String uploadOneFileSubmit(Model model, @ModelAttribute("fileUploadFormData") FileUploadFormData fileUploadFormData, HttpServletRequest req) {
        try
        {
            // Get upload file.
            MultipartFile uploadFile = fileUploadFormData.getFile();

            // Get file name.
            String fileName = uploadFile.getOriginalFilename();

            // Create server side target file path.
            String destFilePath = UPLOAD_FILE_SAVE_FOLDER+fileName;

            File destFile = new File(destFilePath);

            // Save uploaded file to target.
            uploadFile.transferTo(destFile);

            // Set message that will be displayed in return page.
            model.addAttribute("message", "Upload file is saved to '" + destFilePath + "'");

        }catch(IOException ex)
        {
            ex.printStackTrace();
        }finally
        {
            return "upload_file_result";
        }
    }

}

5. File Upload Model Java File.

This file is just used when upload single file. It contains a MultipartFile property, and CommonsMultipartResolver will parse out the upload file and assign the uploaded file to the property.

READ :   Autowire Spring Bean By Type Examples

For multiple file upload, you should use MultipartHttpServletRequest to resolve the upload files. You can see the example code in UploadFileController.java.

FileUploadFormData.java

package com.dev2qa.mvc.fileupload.model;

import org.springframework.web.multipart.MultipartFile;

public class FileUploadFormData {

    /* MultipartFile is used to save the uploaded file content. 
     * */
    private MultipartFile file = null;

    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }
}

6. Messages Properties File.

This file is saved in src/main/resources/config folder. It defines the text messages that will be used in jsp file.

messages_en_US.properties

#Title Labels
upload_file_main_title=Upload File Main
upload_file_result_title=Upload File Result
upload_file_form_title=Upload File Form

7. ResourceBundleViewResolver Configuration Files.

This file is saved in src/main/resources/config folder. It is used to define the returned JSTL view object related jsp pages.

views.properties

# View definition for upload file form.
upload_file_main.(class)=org.springframework.web.servlet.view.JstlView
upload_file_main.url=/pages/upload_file_main.jsp

upload_file_show_form.(class)=org.springframework.web.servlet.view.JstlView
upload_file_show_form.url=/pages/upload_file_show_form.jsp

upload_file_result.(class)=org.springframework.web.servlet.view.JstlView
upload_file_result.url=/pages/upload_file_result.jsp

8. File Upload Example JSP Files.

All the jsp files is saved in src/main/webapp/pages folder. There are three jsp files.

  1. upload_file_main.jsp : Display the example entrance page.
  2. upload_file_show_form.jsp : Display the upload file form page.
  3. upload_file_result.jsp : Display the upload file result page.

8.1 upload_file_main.jsp

This is the upload file example main jsp file, it contains one link and one submit button, all the link will direct user to the upload file form page.

spring mvc upload files example main jsp page

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><spring:message code="upload_file_main_title" /></title>
</head>
<body>
    <a href="${pageContext.request.contextPath}/upload_file/show_upload_file_form.html">Go To Upload File Form Page</a>
    <br/>
    <form action="${pageContext.request.contextPath}/upload_file/show_upload_file_form.html" method="post">
        <input type="submit" value="Go To Upload File Form Page" />
    </form>
</body>
</html>

8.2 upload_file_show_form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><spring:message code="upload_file_form_title" /></title>
</head>
<body>
    <b>1. Upload Multiple File Example</b>
    <form:form modelAttribute="uploadFileFormData"
        action="${pageContext.request.contextPath}/upload_file/upload_multiple_file.html"
        enctype="multipart/form-data"
        method="Post">
        <input type="file" name="fileOne" /><br/>
        <input type="file" name="fileTwo" /><br/>
        <input type="file" name="fileThree" /><br/><br/>
        <input type="submit" value="Submit"/>
    </form:form>
    <hr/>
    <b>2. Upload One File Example</b>
    <form:form modelAttribute="uploadFileFormData"
        action="${pageContext.request.contextPath}/upload_file/upload_one_file.html"
        enctype="multipart/form-data"
        method="Post">
        <input type="file" name="file" /><br/><br/>
        <input type="submit" value="Submit"/>
    </form:form>
</body>
</html>

8.3 upload_file_result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><spring:message code="upload_file_result_title" /></title>
</head>
<body>
    ${ message }
</body>
</html>

9. pom.xml

Our project is managed by maven, so this file is must have. Copy below code to overwrite your pom.xml content.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dev2qa</groupId>
    <artifactId>SpringMVCFileUpload</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>Spring MVC File Upload Download</name>

    <properties>
        <spring.version>5.0.0.BUILD-SNAPSHOT</spring.version>
        <servlet.api.version>3.1.0</servlet.api.version>
    </properties>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>

        <!-- Spring framework used dependencies. -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Servlet used dependencies -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.api.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
        </dependency>

        <!-- File upload used dependencies -->
        <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.2</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>spring-mvc-file-upload-download</finalName>
        <plugins>

            <!-- This plugin is used to create the war file. -->
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

            <!-- This plugin is used to deploy war file to tomcat server. -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <username>tomcat</username>
                    <password>tomcat</password>
                    <!-- update true will override the existing deployed war file in tomcat -->
                    <update>true</update>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>

10. Run Upload Files Example.

  1. Run maven clean, install and deploy the target war file to tomcat server. Please refer How To Deploy A Maven Project To Tomcat From Eclipse.
  2. Then you can run the example with url http://localhost:8080/SpringMVCFileUpload/upload_file/main.html.
  3. If you want to debug the example you can refer to Tomcat Remote Debugging Eclipse.
(Visited 281 times, 6 visits today)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.