Spring 4 MVC - File upload example with Servlet 3.0 multipart request parsing



Spring 4 MVC - File upload example with Servlet 3.0 multipart request parsing

Technologies used:   Java SE 1.8 | Spring 4.3.7.RELEASE | Maven 3.3.9 | Apache Tomcat 7.0.47 | Eclipse Neon.3 

By default, Spring does not allow us to upload files in web application. We can enable it by using one of the following implementation of org.springframework.web.multipart.MultipartResolver.

CommonsMultipartResolver - You need to add commons-fileupload.jar file in your classpath to use CommonsMultipartResolver for handling file upload request.

StandardServletMultipartResolver - You need to register the javax.servlet.MultipartConfigElement in programmatic Servlet registration to use StandardServletMultipartResolver, based on Servlet 3.0  javax.servlet.http.Part API.

In this section, we will use the StandardServletMultipartResolver for uploading single and multiple files in Spring MVC application.

 

 

Jar dependencies

Open pom.xml file of your maven project and add the following dependencies in it .

<dependencies>
<!-- Spring MVC Dependency -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.3.7.RELEASE</version>
</dependency>

<!-- JSTL Dependency -->
<dependency>
  <groupId>javax.servlet.jsp.jstl</groupId>
  <artifactId>javax.servlet.jsp.jstl-api</artifactId>
  <version>1.2.1</version>
</dependency>
<dependency>
  <groupId>taglibs</groupId>
  <artifactId>standard</artifactId>
  <version>1.1.2</version>
</dependency>

<!-- Servlet Dependency -->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>

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

 

Controller class

Create a controller class to handle the single and multiple files upload request as follows.

FileUploadController.java

package com.boraji.tutorial.spring.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author imssbora
 */
@Controller
public class FileUploadController {

   @GetMapping("/")
   public String fileUploadForm(Model model) {

      return "fileUploadForm";
   }

   // Handling single file upload request
   @PostMapping("/singleFileUpload")
   public String singleFileUpload(@RequestParam("file") MultipartFile file, Model model)
         throws IOException {

      // Save file on system
      if (!file.getOriginalFilename().isEmpty()) {
         BufferedOutputStream outputStream = new BufferedOutputStream(
               new FileOutputStream(
                     new File("D:/SingleFileUpload", file.getOriginalFilename())));
         outputStream.write(file.getBytes());
         outputStream.flush();
         outputStream.close();

         model.addAttribute("msg", "File uploaded successfully.");
      } else {
         model.addAttribute("msg", "Please select a valid file..");
      }

      return "fileUploadForm";
   }

   // Handling multiple files upload request
   @PostMapping("/multipleFileUpload")
   public String multipleFileUpload(@RequestParam("file") MultipartFile[] files,
         Model model) throws IOException {

      // Save file on system
      for (MultipartFile file : files) {
         if (!file.getOriginalFilename().isEmpty()) {
            BufferedOutputStream outputStream = new BufferedOutputStream(
                  new FileOutputStream(
                        new File("D:/MultipleFileUpload", file.getOriginalFilename())));

            outputStream.write(file.getBytes());
            outputStream.flush();
            outputStream.close();
         } else {
            model.addAttribute("msg", "Please select at least one file..");
            return "fileUploadForm";
         }
      }
      model.addAttribute("msg", "Multiple files uploaded successfully.");
      return "fileUploadForm";
   }
}

 

JSP View

Create a fileUploadForm.jsp file under src\main\webapp\WEB-INF\views folder to select single or multiple files for sending to controller’s handler method.

fileUploadForm.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>

  <h1>Spring MVC - File Upload Example</h1>
  <hr />

  <h3>Single file Upload</h3>
  <form action="singleFileUpload" method="post" enctype="multipart/form-data">
    <table>
      <tr>
        <td>Select File</td>
        <td><input type="file" name="file"></td>
        <td><button type="submit">Upload</button></td>
      </tr>
    </table>
  </form>
  <br />
  <hr />
  <h3>Multiple file Upload</h3>
  <form action="multipleFileUpload" method="post" enctype="multipart/form-data">
    <table>
      <tr>
        <td>Select Files</td>
        <td><input type="file" name="file" multiple="multiple"></td>
        <td><button type="submit">Upload</button></td>
      </tr>
    </table>
  </form>
  <br>
  <hr />
  <span style="color: red; font-size: 14px;">${msg}</span>

</body>
</html>

 

Spring configuration

Create a web @Configuration class annotated with @EnableWebMvc and @ComponentScan, and declare StandardServletMultipartResolver bean method.The StandardServletMultipartResolver is standard implementation of MultipartResolver based on the Servlet 3.0 API.

WebConfig.java

package com.boraji.tutorial.spring.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.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * @author imssbora
 */

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.boraji.tutorial.spring.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setViewClass(JstlView.class);
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }

   @Bean
   public MultipartResolver multipartResolver() {
      StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
      return resolver;
   }

}

 

Servlet container initialization

In Servlet 3.0 environment, you need to register the javax.servlet.MultipartConfigElement programmatically in your container initializer class to use the Servlet 3.0 based multipart parsing.

So, create a container initializer class by extending the AbstractAnnotationConfigDispatcherServletInitializer class as follows.

MyWebAppInitializer.java

package com.boraji.tutorial.spring.config;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * @author imssbora
 */
public class MyWebAppInitializer
      extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] {};
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }

   @Override
   protected void customizeRegistration(Dynamic registration) {
      
      //Parameters:-
      //   location - the directory location where files will be stored
      //   maxFileSize - the maximum size allowed for uploaded files
      //   maxRequestSize - the maximum size allowed for multipart/form-data requests
      //   fileSizeThreshold - the size threshold after which files will be written to disk
      MultipartConfigElement multipartConfig = new MultipartConfigElement("D:/", 1048576,
            10485760, 0);
      registration.setMultipartConfig(multipartConfig);
   }
}

 

Build + Deploy + Run application

Use the following maven commands to build, deploy and run embedded Tomcat server.

mvn clean install  (This command triggers war packaging)

mvn tomcat7:run (This command run embedded tomcat and deploy war file automatically)

You can refer this link to learn how to run the above commands in Eclipse IDE.


Type the following URLs in browser's address bar to open the file upload from.

http://localhost:8080/

Spring 4 MVC - File upload example  | BORAJI.COM

Select single file and click on Upload button.

Spring 4 MVC - File upload example  | BORAJI.COM

Select multiple files and click on Upload button.

Spring 4 MVC - File upload example  | BORAJI.COM