Spring MVC File Upload Tutorial

1- Introduction

The document is based on:
  • Eclipse 4.6 (NEON)

  • Spring 4 MVC

2- Create Maven project

  • File/New/Other..
Enter:
  • Group ID: org.o7planning
  • Artifact ID: SpringMVCFileUD
  • Package: org.o7planning.springmvcfileud
Project was created.
Do not worry with the error message when Project has been created. The reason is that you have not declared Servlet library.
Using Java >= 6
Project Properties:

3- Configuring Maven & web.xml

Using servlet >= 3
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   version="3.0">

   <display-name>Spring MVC File Update Download</display-name>
 

</web-app>
pom.xml
<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/maven-v4_0_0.xsd">


   <modelVersion>4.0.0</modelVersion>
   <groupId>org.o7planning</groupId>
   <artifactId>SpringMVCFileUD</artifactId>
   <packaging>war</packaging>
   <version>0.0.1-SNAPSHOT</version>
   <name>SpringMVCFileUD Maven Webapp</name>
   <url>http://maven.apache.org</url>

   <dependencies>
   
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>3.8.1</version>
           <scope>test</scope>
       </dependency>


       <!-- Servlet API -->
       <!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <scope>provided</scope>
       </dependency>

       <!-- Jstl for jsp page -->
       <!-- http://mvnrepository.com/artifact/javax.servlet/jstl -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
           <version>1.2</version>
       </dependency>


       <!-- JSP API -->
       <!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
       <dependency>
           <groupId>javax.servlet.jsp</groupId>
           <artifactId>jsp-api</artifactId>
           <version>2.2</version>
           <scope>provided</scope>
       </dependency>


       <!-- Spring dependencies -->
       <!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-core</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>

       <!-- http://mvnrepository.com/artifact/org.springframework/spring-web -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-web</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>

       <!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>


       <!-- Apache Commons FileUpload -->
       <!-- http://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
       <dependency>
           <groupId>commons-fileupload</groupId>
           <artifactId>commons-fileupload</artifactId>
           <version>1.3.1</version>
       </dependency>

       <!-- Apache Commons IO -->
       <!-- http://mvnrepository.com/artifact/commons-io/commons-io -->
       <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.4</version>
       </dependency>


   </dependencies>



   <build>
       <finalName>SpringMVCFileUD</finalName>
       <plugins>

           <!-- Config: Maven Tomcat Plugin -->
           <!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
           <plugin>
               <groupId>org.apache.tomcat.maven</groupId>
               <artifactId>tomcat7-maven-plugin</artifactId>
               <version>2.2</version>
               
               <!-- Config: contextPath and Port (Default - /SpringMVCFileUD : 8080) -->
               
               <!--
               <configuration>
                   <path>/</path>
                   <port>8899</port>
               </configuration>
               -->
           </plugin>
       </plugins>
   </build>
   
</project>

4- Configuring Spring MVC

SpringWebAppInitializer.java
package org.o7planning.springmvcfileud.config;

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

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

public class SpringWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(ApplicationContextConfig.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher",
                new DispatcherServlet(appContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        // UtF8 Charactor Filter.
        FilterRegistration.Dynamic fr = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);

        fr.setInitParameter("encoding", "UTF-8");
        fr.setInitParameter("forceEncoding", "true");
        fr.addMappingForUrlPatterns(null, true, "/*");
    }

}
WebMvcConfig.java
package org.o7planning.springmvcfileud.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

     
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // Default..
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}
You need to declare multipartResolver Spring BEAN. In this Spring Bean, you can configure the maximum upload file size.
ApplicationContextConfig.java
package org.o7planning.springmvcfileud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan("org.o7planning.springmvcfileud.*")
public class ApplicationContextConfig {

    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }

    @Bean(name = "multipartResolver")
    public MultipartResolver getMultipartResolver() {
        CommonsMultipartResolver resover = new CommonsMultipartResolver();
        // 1MB
        resover.setMaxUploadSize(1 * 1024 * 1024);

        return resover;
    }

}

5- Controllers & Form

MyFileUploadController.java
package org.o7planning.springmvcfileud.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.o7planning.springmvcfileud.form.MyUploadForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
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.commons.CommonsMultipartFile;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

@Controller
public class MyFileUploadController {


  @InitBinder
  public void initBinder(WebDataBinder dataBinder) {
      Object target = dataBinder.getTarget();
      if (target == null) {
          return;
      }
      System.out.println("Target=" + target);

      if (target.getClass() == MyUploadForm.class) {

          // Register to handle the conversion between the multipart object
          // and byte array.
          dataBinder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
      }
  }

  // GET: Show upload form page.
  @RequestMapping(value = "/uploadOneFile", method = RequestMethod.GET)
  public String uploadOneFileHandler(Model model) {

      MyUploadForm myUploadForm = new MyUploadForm();
      model.addAttribute("myUploadForm", myUploadForm);

      // Forward to "/WEB-INF/pages/uploadOneFile.jsp".
      return "uploadOneFile";
  }

  // POST: Do Upload
  @RequestMapping(value = "/uploadOneFile", method = RequestMethod.POST)
  public String uploadOneFileHandlerPOST(HttpServletRequest request, //
          Model model, //
          @ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {

      return this.doUpload(request, model, myUploadForm);

  }

  // GET: Show upload form page.
  @RequestMapping(value = "/uploadMultiFile", method = RequestMethod.GET)
  public String uploadMultiFileHandler(Model model) {

      MyUploadForm myUploadForm = new MyUploadForm();
      model.addAttribute("myUploadForm", myUploadForm);

      // Forward to "/WEB-INF/pages/uploadMultiFile.jsp".
      return "uploadMultiFile";
  }

  // POST: Do Upload
  @RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
  public String uploadMultiFileHandlerPOST(HttpServletRequest request, //
          Model model, //
          @ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {

      return this.doUpload(request, model, myUploadForm);

  }

  private String doUpload(HttpServletRequest request, Model model, //
          MyUploadForm myUploadForm) {

      String description = myUploadForm.getDescription();
      System.out.println("Description: " + description);


      // Root Directory.
      String uploadRootPath = request.getServletContext().getRealPath("upload");
      System.out.println("uploadRootPath=" + uploadRootPath);

      File uploadRootDir = new File(uploadRootPath);
      //
      // Create directory if it not exists.
      if (!uploadRootDir.exists()) {
          uploadRootDir.mkdirs();
      }
      CommonsMultipartFile[] fileDatas = myUploadForm.getFileDatas();
      //
      List<File> uploadedFiles = new ArrayList<File>();
      for (CommonsMultipartFile fileData : fileDatas) {

          // Client File Name
          String name = fileData.getOriginalFilename();
          System.out.println("Client File Name = " + name);

          if (name != null && name.length() > 0) {
              try {
                  // Create the file on server
                  File serverFile = new File(uploadRootDir.getAbsolutePath() + File.separator + name);

     
                  // Stream to write data to file in server.
                  BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
                  stream.write(fileData.getBytes());
                  stream.close();
                  //
                  uploadedFiles.add(serverFile);
                  System.out.println("Write file: " + serverFile);
              } catch (Exception e) {
                  System.out.println("Error Write file: " + name);
              }
          }
      }
      model.addAttribute("description", description);
      model.addAttribute("uploadedFiles", uploadedFiles);
      return "uploadResult";
  }

}
MyUploadForm.java
package org.o7planning.springmvcfileud.form;

import org.springframework.web.multipart.commons.CommonsMultipartFile;

public class MyUploadForm {

    private String description;
    
    // Upload files.
    private CommonsMultipartFile[] fileDatas;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public CommonsMultipartFile[] getFileDatas() {
        return fileDatas;
    }

    public void setFileDatas(CommonsMultipartFile[] fileDatas) {
        this.fileDatas = fileDatas;
    }
    
}

6- Views

_menu.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<div style="border:1px solid #ccc;padding:5px;">

  <a href="${pageContext.request.contextPath}/uploadOneFile">Upload One File</a>

  &nbsp;|&nbsp;

  <a href="${pageContext.request.contextPath}/uploadMultiFile">Upload Multi File</a>
 
 
</div>
Note: For data update form, you need to have the attribute: enctype = "multipart/form-data".
uploadOneFile.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload One File</title>
</head>
<body>
    <jsp:include page="_menu.jsp"/>
    
    <h3>Upload One File:</h3>

    <!-- MyUploadForm -->
    <form:form modelAttribute="myUploadForm" method="POST"
                        action="" enctype="multipart/form-data">

        Description:
        <br>
        <form:input path="description" style="width:300px;"/>                
        <br/><br/>  
            
        File to upload: <form:input path="fileDatas" type="file"/><br />  
        
          
        <input type="submit" value="Upload">
        
    </form:form>
    
</body>

</html>
uploadMultiFile.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload Multi File</title>
</head>
<body>
   <jsp:include page="_menu.jsp"/>
   
   <h3>Upload Multiple File:</h3>
   
    <!-- MyUploadForm -->
    <form:form modelAttribute="myUploadForm" method="POST"
                        action="" enctype="multipart/form-data">
        
        Description:
        <br>
        <form:input path="description" style="width:300px;"/>                
        <br/><br/>                 
    
        File to upload (1): <form:input path="fileDatas" type="file"/><br />      
        File to upload (2): <form:input path="fileDatas" type="file"/><br />    
        File to upload (3): <form:input path="fileDatas" type="file"/><br />    
        File to upload (4): <form:input path="fileDatas" type="file"/><br />    
        File to upload (5): <form:input path="fileDatas" type="file"/><br />    
        
        <input type="submit" value="Upload">
         
    </form:form>
    
    
</body>
</html>
uploadResult.jsp
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    
<html>
<head>
<meta charset="UTF-8">
<title>Upload Result</title>
</head>
<body>
    <jsp:include page="_menu.jsp"/>
   
    <h3>Uploaded Files:</h3>
    
    Description: ${description}
    
    <br/>
    
    <c:forEach items="${uploadedFiles}" var="file">
           - ${file} <br>
    </c:forEach>

</body>
</html>

7- Run Application

Run Configurations:

Enter:
  • Name: Run SpringMVCFileUD
  • Base directory: ${workspace_loc:/SpringMVCFileUD}
  • Goals: tomcat7:run