Main Tutorials

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
    //https://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 Author

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

Comments

Subscribe
Notify of
32 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Crystal
6 years ago

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?

k c
6 years ago

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.

Ayushmaan Shrivastava
3 years ago

org.springframework.web.multipart.MultipartException: Current request is not a multipart request
This is the error I’m facing while running the applicatin.

Gonzalo Oviedo Lambert
5 years ago

You saved my life Man. I have one year experience with Spring Boot Rest and Java, but my memory is like crap, your example works like a charm and thank you very much for putting the import statements, it is a very crucial step.

One suggestion for the people, use Spring Boot Initializer (Search in Google) and import the proyect like Maven in Eclipse.

And by the way (my english sucks), your example maybe save thousands to an hospital, literal.

Thank you.

Abhishek Aradhya
4 years ago

Hi I have implemented document upload feature in my project in the same manner. All the uploaded documents get saved in the given folder in my server and I am saving the unique reference in the data base for future used and to avoid duplicates. But in my application when ever user uploads new document in the edit old reference will get replaced by new reference in the database. And the old file stays remain in the Folder which is no use. I want to delete the old file as soon as new file uploaded or by using some scheduled job. Can Anybody suggest the best way to remove the unused files using spring boot instead of Java file system. Since the storage is keep filling.
Thanks In advance

sonal k
4 years ago

Getting FileUploadException: the request was rejected because no multipart boundary was found
when trying from postman

Ingo
4 years ago

Hello,
Thank you for your articles, I guess I am a regular customer here and I hope that you keep on working with these tutorials which are always concise and informative!

Following your example and then using the example from spring.io (https://spring.io/guides/gs/spring-boot/)
I am wondering about two things – what they have in common is that I would like to do some ‘business-code’ and I hope that you can shed some light.
First of all, if I would like to tamper wit the file ( say it is an xml-file and I would like to transform the numeric values in one column ) and let the user download the tampered file where should I do that ?
the second would be if I save the file, for instance an image, and would like to store the exif-data – where in the code should I pull out that exif data to save in a database ?

best, i

Aakansha
5 years ago

after upload the file getting exception java.nio.file.FileSystemException: F:\temp\test.xlsx: The device is not ready.

Misha
6 years ago

Super !

Sayantan
6 years ago

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.

Aaron
6 years ago

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

Nik
10 months ago

how handle multipart/related ?

saida
1 year ago

Hi,

uploading xml file. that file convert xml into java object.

can u give the some examples

Thank you

Scott Macdonald
3 years ago

Excellent content – like usual

CYW
4 years ago

why it says “Request method ‘GET’ not supported” when access “http://localhost:8080/”

janken
5 years ago

thanks

swallow
5 years ago

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
5 years ago
Reply to  swallow

look up you upload jsp at enctype=””

Xolo
6 years ago

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

Mohan
4 years ago
Reply to  Xolo

yes mee too, what is the solution?

mohan
4 years ago
Reply to  Mohan

when i was using “RestController” i was getting “upload” as response, but when i change to “Controller” in UploadController.java, it is working fine.

harish
6 years ago

could you post the JUNIT test?

Krish
6 years ago

how to take the file path from the above example

David
6 years ago

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
6 years ago

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

Roshen
6 years ago

How to maintain duplicate files names?

Dharshna
6 years ago

Your awesome…. Your make me happy sleep

dipesh Pandey
6 years ago

how to rename the file to certain pattern .

ables lekzy
6 years ago

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

Co?kun
6 years ago

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.

Tapio Niemelä
6 years ago

Once again thanks for clear example

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

Herculano Cunha
6 years ago

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

Path /resource/img/upload