Handling File Upload in Spring MVC Application

Any typical web application requires a file upload functionality which enable users to upload certain files like an image or a document. Such files are encoded as multipart form data rather than simple text. To handle file uploads in a Spring MVC application we need to configure a multipart resolver so that DispatcherServlet can identify and read multipart requests.


Configuring Multipart Resolver

Spring provides two out-of-box implementation of MultipartResolver:

  • StandardServletMultipartResolver - Uses Servlet 3.0 support for file upload. (for Servlet 3.0 post 3.0 containers.)
  • CommonsMultipartResolver - Uses Jakarta Commons File Upload (for pre Servlet 3.0 containers.)

StandardServletMultipartResolver

To use StandardServletMultipartResolver in our application we simply need to declare it as a Spring bean.

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

Other configuration of multipart details like, the temporary folder when the file should be placed when being uploaded or the maximum file size etc. are to be done as part of DispatcherServlet configuration, in the web.xml or the ServletInitializer class. For JavaConfig based application we need to override the customizeRegistration() method of AbstractAnnotationConfigDispatcherServletInitializer class in our application initializer class as shown below:

@Override
protected void customizeRegistration(Dynamic registration) {
    registration.setMultipartConfig(new MultipartConfigElement("/tmp/uploads"));
}

Here we specified the temporary folder path to store the file when being uploaded. We can use other constructors of MultipartConfigElement to specify other information like maxFileSize, etc. In this case the maxFileSize will be unlimited (as unspecified).

Shown below is the configuration using web.xml

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <multipart-config>
	<location>/tmp/uploads</location>
	<max-file-size>1048576</max-file-size>
    </multipart-config>
</servlet>

The max-file-size of 1MB is specified (1024 X 1024 bytes).


CommonsMultipartResolver

CommonsMultipartResolver can be used in a similar way as we used StandardServletMultipartResolver. However in this case we need not necessarily specify a temporary upload location. The servlet container’s temporary directory is treated as a default temporary upload directory. However we can specify a different directory if required.

CommonsMultipartresolver can be declared as a Spring bean as follows:

@Bean
public MultipartResolver multipartResolver() throws IOException {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    /** Additional Configuration **/
    multipartResolver.setUploadTempDir(new FileSystemResource("/tmp/uploads"));
    multipartResolver.setMaxUploadSize(1048576);
    return multipartResolver;
}

Handling Multipart Request

Before we can accept multipart request in the Spring MVC controller we need to specify certain attributes in the html form tag which we use to submit multipart data. We need to set the ‘enctype’ (encryption type) attribute of the form tag to ‘multipart/form-data’. This tells the browser to submit the form data as multipart data.

<form action="upload" method="post" enctype="multipart/form-data">
    <label>Upload Pic</label>
    <input type="file" name="picture" accept="image/png">
    <input type="submit" value="Submit">
</form>

Notice the use of accept attribute in the input tag, it is used to restrict the type of files that can be uploaded using this form, a png image in this case.

Now it's time to handle the multipart request at the Spring MVC controller end. To do so we need to annotate the controller method parameter with @RequestPart.

@RequestMapping(value="upload", method=RequestMethod.POST)
public String sayHello(@RequestPart("picture") MultipartFile picture) throws IOException{
    picture.transferTo(new File("/tmp/uploads/"+picture.getOriginalFilename()));
	
    System.out.println("Uploaded File Details:");
    System.out.println("FileName: "+ picture.getOriginalFilename());
    System.out.println("Size: "+ picture.getSize() +" bytes");
    System.out.println("Content Type: "+ picture.getContentType());
    System.out.println("Multipart name: "+ picture.getName());
	
    return "success";
}

We received the multipart data as a MultipartFile. Spring provides a MultipartFile object to ease processing of multipart data. The MultipartFile defines many methods that can be used to process multipart data. One such method is transferTo() which can be used to conveniently transfer the multipart file to a specific location in the file system. Some other useful method of the MultipartFile is shown above in the example code.


Download Source Code

You can download the source code of the example application discussed in this article. The source code below uses StandardServletMultipartResolver.

POPULAR ARTICLES

Creating Conditional Beans in Spring

The concept of condition beans enables Spring to restrict the creation of any bean depending on the evaluation of a condition. These beans get created only when a preset condition is evaluated as true

View Article

Accepting Request Param and Path Variable in Spring Controller

Spring MVC provides various ways through which a client browser can pass data to the Controller. In this article we will discuss about accepting Request Parameters and Path Variables in Spring Contr..

View Article

Generate Namespace & Schema Information using JAXB

Most xml documents used in enterprise applications makes use of namespace to avoid element name conflicts. This article talks about generating these namespace and schema information when marshaling...

View Article

Switching Database Profile using Spring Profiles

We are most likely to have separate db configuration for different environment like development and production environment. Spring profiles provide a convenient way to switch db profiles at runtime.

View Article

SQL and its Sub-Languages

SQL (Structured Query Language) is a language understood by most modern databases. It is an ANSI (American National Standard Institute) standard language which is used to manipulate databases.

View Article

Introducing JUnit Rule

Junit Rules allows developers to add additional functionalities that can applied to all test methods in a test class. It is similar to the concept of custom test runners but with reduced restrictions.

View Article

Addressing Ambiguity in Spring Autowiring

Spring autowiring is powerful concept, but we should be very cautious while using it. We may end up in creating ambiguity while autowiring beans, which will cause autowiring to fail.

View Article

Creating and Using Synonym in Oracle Database

Synonyms are database objects used to provide duplicate names to existing objects in the database. It is just an alternate name used to hide the original name of the object.

View Article

Creating and Using Sequence in Oracle Database

A sequence is used to auto-generate numbers in ascending or descending order which can serve as a primary key or a part of it (in case of composite key).

View Article

Creating and Manipulating Constraints in Oracle Database

Constraints are used to impose certain rules on columns to avoid invalid data entry into the table. If any of the constraint is violated the operation fails.

View Article

Integrating Log4J with Perf4J for Performance Logging

Perf4j is an open source logging framework used primarily for monitoring performance statistics in java applications. Log4j has the ability to integrate with perf4j to capture performance data.

View Article

Tagging in GIT

Tagging allows us to mark a specific point in the commit history or snapshot. A tag is typically used to mark a project release. This article shows how to create tags in Git.

View Article