Uploading A Files with Spring MVC

In this article of Spring MVC, We are going to cover the uploading a file in Spring MVC.File Uploading is a very common task in any web application. We are going to see how Spring Boot can help us to speed up the process.

 

Introduction

If you are working in web development, chances are that you may have already worked on file upload functionality or feature in your application. In this post of uploading a file in Spring MVC, we are going to take a look at the different features available in the framework to accomplish this task.

Spring MVC provides a pluggable architecture for the file upload feature.MultipartResolver from the org.springframework.web.multipart package is a strategy for parsing multipart requests including file uploads. There is one implementation based on Commons FileUpload and another based on Servlet 3.0 multipart request parsing. We are going to use Spring Boot for our example but the concept holds true to non Spring Boot application and we will highlight the differences where applicable.

 

1. Spring Boot File Upload

Spring Boot really make it easy for us to configure the application. For Spring Boot, we do not need to configure or create any servlet for us as this is automatically taken care by Spring Boot autoconfiguration. We need to make sure that the required auto-configuration are added as part of the pom.xml setup. To start working with Spring Boot, we need to have the “spring-boot-starter-web“.

 

1.1 Maven Setup

For our example, let’s add necessary dependencies for our Maven project.

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
 </dependencies>

We are using Thymeleaf for building the UI.

As part of auto-configuring Spring MVC, Spring Boot will create a MultipartConfigElement bean and make itself ready for file uploads

 

1.2 Uploading Single File

Let’s take a look at the controller for uploading a given file on our server. This example storing the file in the temp folder, but you can always create a simple storage service to store this file data in Database or NoSQL Db etc.

@GetMapping(value = "/saveFile")
  public String getFileU(Model model) {
   return "uploadForm";
  }

  @PostMapping(value = "/saveFile")
  public String handleFileUpload(@RequestParam("file") MultipartFile file, Model model) {

   //Logic to store data in temp file or in DB
   model.addAttribute("uploadedFile", file);
   return "uploadForm";
  }

Let’s take a close look at some important points

  • First GET method brings out the file upload form.
  • POST / is geared to handle a multi-part message file and give it to the file saving logic (service or utility class).

 

1.3 HTML For FileUpload

Here is a very simple HTML based on Thymeleaf to build our file upload UI.

<html xmlns:th="http://www.thymeleaf.org">
<body>

<div th:if="${uploadedFile}">
    <h2> Uploaded File Details </h2>
    <table>
        <tr>

            <td>FileName:</td>
            <td th:text="${uploadedFile.originalFilename}"></td>
        </tr>
        <tr>
            <td>Type:</td>
            <td th:text="${uploadedFile.contentType}"></td>
        </tr>
    </table>
</div>
<div>
    <h2> Uploaded New File </h2>
    <form method="POST" enctype="multipart/form-data" action="/saveFile">
        <table>
            <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
            <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
        </table>
    </form>
</div>
</body>
</html>

The first part displays the name and the content type of the file (when an upload is complete) while the second half of the HTML is for letting the user choose and upload a file.

 

1.4 Uploading Multiple File

In case you face a requirement where the customer should be able to upload multiple files, everything remain the same except for two changes to the above example.

  1. We put multiple input fields inside the form.
  2. Change the MultipartFile file to MultipartFile[] files.

Let’s see these code changes:

@PostMapping(value = "/saveFiles")
   public String handleFileUpload(@RequestParam("files") MultipartFile[] files, Model model) {

    //Logic to store data in temp file or in DB
    model.addAttribute("uploadedFile", files);
    return "uploadForm";
}
<html xmlns:th="http://www.thymeleaf.org">
<body>

<div th:if="${uploadedFile}">
    <h2> Uploaded File Details </h2>
    <table>
        <tr th:each="file: ${uploadedFile}">
            <td th:text="${file.originalFilename}">File Name</td>
            <td th:text="${file.contentType}">File Type:</td>
        </tr>
    </table>
</div>
<div>
    <h2> Uploaded New File </h2>
    <form method="POST" enctype="multipart/form-data" action="/saveFiles">
        <table>
            <tr><td>File to upload 1:</td><td><input type="file" name="files" /></td></tr>
            <tr><td>File to upload 2:</td><td><input type="file" name="files" /></td></tr>
            <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
        </table>
    </form>
</div>
</body>
</html>

 

1.5 Tuning File Upload

Spring Boot provides a number of properties which we can use to fine tune our file upload process. You can configure these properties using application.properties file.Here is the list for your reference:

# MULTIPART (MultipartProperties)
spring.servlet.multipart.enabled=true # Whether to enable support of multipart uploads.
spring.servlet.multipart.file-size-threshold=0B # Threshold after which files are written to disk.
spring.servlet.multipart.location= # Intermediate location of uploaded files.
spring.servlet.multipart.max-file-size=1MB # Max file size.
spring.servlet.multipart.max-request-size=10MB # Max request size.
spring.servlet.multipart.resolve-lazily=false # Whether to resolve the multipart request lazily at the time of file or parameter access

 

2. Spring MVC File Upload

Most of the above concept will remain the same even if you are not using the Spring Boot in your application. In this section, I am going to highlight the main differences or additional changes required for Spring MVC file upload.

 

2.1 Maven Dependencies

We need to add the Apache Commons FileUpload dependency in our pom.xml file

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

 

2.2 CommonsMultipartResolver Bean

The second step of our configuration involves defining CommonsMultipartResolver bean for our application. This bean is useful to customize the file upload behavior for our application.

@Bean
 public CommonsMultipartResolver multipartResolver() {
  CommonsMultipartResolver resolver = new CommonsMultipartResolver();
  resolver.setDefaultEncoding("utf-8");
  resolver.setResolveLazily(false);
  resolver.setMaxUploadSize(200000);
  return resolver;
 }

 

3. File Upload and Servlet 3.0

In case you like to use Servlet 3.0 feature, you need to make sure to configure a couple of items before using it. Let’s see those details:

  1. Set a MultipartConfigElement on the Servlet registration.
public class WebbAppInit implements WebApplicationInitializer {

 private int MAX_UPLOAD_SIZE = 2 * 1024 * 1024;

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

  AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
  rootContext.register(SpringMvcFileUploadApplication.class);

  // Manage the lifecycle of the root application context
  servletContext.addListener(new ContextLoaderListener(rootContext));

  // Register and map the dispatcher servlet
  ServletRegistration.Dynamic dispatcher =
   servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
  dispatcher.setLoadOnStartup(1);
  dispatcher.addMapping("/");
  MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/temp",
   MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, 0);
 }
}

Read Spring WebApplicationInitializer for more details.

 

Summary

In this article, we learn the basic of uploading a file in Spring MVC. We covered how you can use Spring Boot autoconfiguration to speed up the development of the file uploading features. In the second part of the article, we get an idea about the different steps needed to configure file uploading in Spring MVC without Spring Boot.

Source code for this article can be found on the GitHub.

Umesh

Hello!! I am Umesh- an engineer by profession and a photographer by passion.I like to build stuff on the web using OSS and love to capture the world through my lens.

follow me on:

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
0 Comment authors
Recent comment authors

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

  Subscribe  
newest oldest most voted
Notify of