Spring MVC Multiple Files Upload Example

In my previous tutorial I had shown Spring MVC Single File Upload Example. In this tutorial I am going to show an example on how to upload multiple files using Spring MVC. I am going to use Spring Boot framework to upload multiple files.

I am using Thymeleaf as a template file for displaying UI (User Interface). I have put basic validation for the file upload form. If you do not select any file for upload then you will see an error message.

Prerequisites

Java at least 8, Spring Boot 2.3.3, Gradle 6.5.1, Maven 3.6.3

Project Setup

Either create gradle or maven based project in your favorite IDE or tool. The name of the project is spring-mvc-multiple-files-upload.

If you creating gradle based project then you can use below build.gradle script:

buildscript {
	ext {
		springBootVersion = '2.3.3.RELEASE'
	}
	
    repositories {
    	mavenCentral()
    }
    
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id 'java-library'
    id 'org.springframework.boot' version "${springBootVersion}"
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    mavenCentral()
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
	implementation("org.springframework.boot:spring-boot-starter-thymeleaf:${springBootVersion}")
}

If you are creating maven based project then you can use below pom.xml file:

<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.roytuts</groupId>
	<artifactId>spring-mvc-multiple-files-upload</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.3.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

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

    <build>
        <plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>at least 8</source>
					<target>at least 8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Spring Controller

Spring controller is responsible for handling any request and response for the clients. Here I have defined two endpoints in the following Spring controller class.

The root path (“/”) displays the file upload form or page where a browse button is given for selecting multiple files.

Other endpoint path (“/upload/files”) upload the selected files into server location.

package com.roytuts.spring.mvc.multiple.files.upload;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

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;

@Controller
public class FileUploadController {

	private final String UPLOAD_FOLDER = "/upload";

	@GetMapping("/")
	public String uploadFiles() {
		return "uploadfiles";
	}

	@PostMapping("upload/files")
	public String handleFilesUpload(@RequestParam("files") MultipartFile files[], Model map) {
		StringBuilder sb = new StringBuilder();

		for (MultipartFile file : files) {
			if (!file.isEmpty()) {
				try {
					if (!Files.exists(Paths.get(UPLOAD_FOLDER))) {
						try {
							Files.createDirectories(Paths.get(UPLOAD_FOLDER));
						} catch (IOException ioe) {
							ioe.printStackTrace();
						}
					}

					Files.copy(file.getInputStream(), Paths.get(UPLOAD_FOLDER, file.getOriginalFilename()));
					sb.append("You successfully uploaded " + file.getOriginalFilename() + "!\n");

					map.addAttribute("msg", sb.toString());
				} catch (IOException | RuntimeException e) {
					sb.append("Failued to upload " + (file != null ? file.getOriginalFilename() : "") + " => "
							+ e.getMessage() + String.valueOf(e) + "\n");

					map.addAttribute("msg", sb.toString());
				}
			} else {
				sb.append("Failed to upload file\n");
				map.addAttribute("msg", sb.toString());
			}
		}

		return "uploadfiles";
	}

}

View File

The view file or Thymeleaf template file is kept under the classpath directory src/main/resources/templates.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring MVC Multiple Files Upload Example</title>
</head>
<body>
	<h2>Spring MVC Multiple Files Upload Example</h2>

	<div th:if="${msg != null}" th:text="${msg}"></div>

	<form name='upload_files' enctype="multipart/form-data"
		th:action="@{/upload/files}" method='POST'>
		Select Files: <input type="file" name="files" multiple="multiple" /> <br />
		<br /> <input value="Upload" type="submit" />
	</form>
</body>
</html>

Main Class

A class with @SpringBootApplication and main method is enough to deploy the application into embedded Tomcat server.

package com.roytuts.spring.mvc.multiple.files.upload;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringMvcMultipleFilesUploadApp {

	public static void main(String[] args) {
		SpringApplication.run(SpringMvcMultipleFilesUploadApp.class, args);
	}

}

Testing the Application

When you hit the URL http://localhost:8080/ in the browser, you will see below page:

spring multiple files upload

If you try to click on Upload button without selecting any file:

spring multiple files upload

When files successfully uploaded to the destination directory:

I have uploaded three different files and after successful upload their names are shown on the UI.

Source Code

Download

Thanks for reading.

Leave a Reply

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