Spring Boot file upload example

This article shows you how to upload a file in Spring Boot web application.

Tools used :

  1. Spring Boot 1.4.3.RELEASE
  2. Spring 4.3.5.RELEASE
  3. Thymeleaf
  4. Maven
  5. Embedded Tomcat 8.5.6

1. Project Structure

A standard project structure.

spring-boot-file-upload-example-directory

2. Project Dependency

Spring boot dependencies, no need extra library for file upload.

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>com.mkyong</groupId>
    <artifactId>spring-boot-file-upload</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>

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

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

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

        <!-- hot swapping, disable cache for template, enable live reload -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- Package as an executable jar/war -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3. File Upload Example

Spring boot file upload, zero configuration.

3.1 In the Controller, maps the uploaded file to MultipartFile

UploadController.java

package com.mkyong.controller;

import org.springframework.stereotype.Controller;
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;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

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

@Controller
public class UploadController {

    //Save the uploaded file to this folder
    private static String UPLOADED_FOLDER = "F://temp//";

    @GetMapping("/")
    public String index() {
        return "upload";
    }

    @PostMapping("/upload") // //new annotation since 4.3
    public String singleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {

        if (file.isEmpty()) {
            redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
            return "redirect:uploadStatus";
        }

        try {

            // Get the file and save it somewhere
            byte[] bytes = file.getBytes();
            Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
            Files.write(path, bytes);

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded '" + file.getOriginalFilename() + "'");

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "redirect:/uploadStatus";
    }

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

}

3.2 In thymeleaf, just some normal HTML file tags.

upload.jsp

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

<h1>Spring Boot file upload example</h1>

<form method="POST" action="/upload" enctype="multipart/form-data">
    <input type="file" name="file" /><br/><br/>
    <input type="submit" value="Submit" />
</form>

</body>
</html>

3.3 Another page for upload status

uploadStatus.jsp

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>

<h1>Spring Boot - Upload Status</h1>

<div th:if="${message}">
    <h2 th:text="${message}"/>
</div>

</body>
</html>

4. Max upload size exceeded

To handle the max upload size exceeded exception, declares a @ControllerAdvice and catch the MultipartException

GlobalExceptionHandler.java

package com.mkyong.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@ControllerAdvice
public class GlobalExceptionHandler {

    //https://jira.spring.io/browse/SPR-14651
    //Spring 4.3.5 supports RedirectAttributes
    @ExceptionHandler(MultipartException.class)
    public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {

        redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
        return "redirect:/uploadStatus";

    }

    /* Spring < 4.3.5
	@ExceptionHandler(MultipartException.class)
    public String handleError2(MultipartException e) {

        return "redirect:/errorPage";

    }*/

}

5. Tomcat Connection Reset

If you deployed to Tomcat, configure the maxSwallowSize to avoid this Tomcat connection reset issue. For embedded Tomcat, declares a TomcatEmbeddedServletContainerFactory like the following :

SpringBootWebApplication.java

package com.mkyong;

import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringBootWebApplication {

    private int maxUploadSizeInMb = 10 * 1024 * 1024; // 10 MB

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

    //Tomcat large file upload connection reset
    //http://www.mkyong.com/spring/spring-file-upload-and-connection-reset-issue/
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {

        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

        tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
            if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
                //-1 means unlimited
                ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
            }
        });

        return tomcat;

    }

}

6. Multipart File Size

By default, Spring Boot max file upload size is 1MB, you can configure the values via following application properties :

application.properties

#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
#search multipart
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=10MB

7. DEMO

Start Spring Boot with the default embedded Tomcat mvn spring-boot:run.

Terminal

$ mvn spring-boot:run
 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.3.RELEASE)
 
2017-01-21 07:48:53 INFO  com.mkyong.SpringBootWebApplication - Starting SpringBootWebApplication on MKYONG-WIN10 with PID 2384 (E:\spring-boot-file-upload\target\classes started by mkyong in E:\spring-boot-file-upload)
2017-01-21 07:48:53 DEBUG com.mkyong.SpringBootWebApplication - Running with Spring Boot v1.4.3.RELEASE, Spring v4.3.5.RELEASE
2017-01-21 07:48:53 INFO  com.mkyong.SpringBootWebApplication - No active profile set, falling back to default profiles: default
2017-01-21 07:48:55 INFO  com.mkyong.SpringBootWebApplication - Started SpringBootWebApplication in 2.54 seconds (JVM running for 2.924)

7.1 Access http://localhost:8080/

spring-boot-file-upload-example

7.2 Select a file and upload it.

spring-boot-file-upload-example-2

7.3 Select a file larger than 10mb, you will visit this page.

spring-boot-file-upload-example-3

8. Download Source Code

References

  1. Spring Boot common application properties
  2. Spring MVC file upload example
  3. Spring @ExceptionHandler and RedirectAttributes
  4. Spring Boot Hello World Example – Thymeleaf

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
swallow
Guest
swallow

Thanks for this awesome post, I have an issue using this on my application : “Current request is not a multipart request”
Any idea about that please ?

ximenlv
Guest
ximenlv

look up you upload jsp at enctype=””

Xolo
Guest
Xolo

Hi,
I am getting simply text as upload when hitting http://localhost:8080/

Misha
Guest
Misha

Super !

harish
Guest
harish

could you post the JUNIT test?

k c
Guest
k c

Good to know about the connection reset issue.
But, note that in SpringBoot 2.0.0 (still in RC1 phase), use class TomcatServletWebServerFactory in place of TomcatEmbeddedServletContainerFactory.

Crystal
Guest
Crystal

Hi, I’m using JPA + Spring Boot. I need to upload one file, save it in disk and save the reference into database. How can I do this?

Sayantan
Guest
Sayantan

I am using Spring Boot. How can I allow non-executable type files only? Do I need to check file content type and then hard code all executable types to restrict in the controller code? Or is there any other way to mention all unwanted file types? If someone changes the file type what will happen? E.g. test.exe ->test.exe.png , test.exe->test.txt.

Krish
Guest
Krish

how to take the file path from the above example

David
Guest
David

Hi.
In uploadStatus I would like to show a table with all the info of the uploaded file. In your method singleFileUpload I added a Model to pass the info of file to uploadStatus, but I’m not be able to do it.

Any suggestion?
Thanks for your posts!!!!

Mark andrew Ong
Guest
Mark andrew Ong

Hi,
How can we test this service via rest clieent (preferably postman). Thanks.

Roshen
Guest
Roshen

How to maintain duplicate files names?

Dharshna
Guest
Dharshna

Your awesome…. Your make me happy sleep

dipesh Pandey
Guest
dipesh Pandey

how to rename the file to certain pattern .

ables lekzy
Guest
ables lekzy

Upload works fine but how do you display the uploaded image in . Could not get that to work with thymeleaf

Co?kun
Guest
Co?kun

Hi, i am having hard times with this issue:

I downloaded your project and ran perfectly first.I tried to create a client using classical http connection and then I tested on my local w?ndows machine and it ran with in two ways. Finally, i wanted to test on linux server and deployed your app on l?nux server. although it ran via browser, i gave java.net.ConnectException: connection timed out when i tried to use my client code. And I also set my client timeout parameter.

I am wondering that if you have any idea about that or not.

Best regards.

Aaron
Guest
Aaron

You’re awesome mkyong, your examples have been helpful for many years.

Tapio Niemelä
Guest
Tapio Niemelä

Once again thanks for clear example

There’s one mistake, upload.jsp should be upload.html

Herculano Cunha
Guest
Herculano Cunha

I can upload, but can’t get image after upload spring boot using angularjs, only after application restart.

Path /resource/img/upload