Spring has built-in multipart support to handle fileuploads in web applications. The design for the multipart support is done with pluggable MultipartResolver objects. This object available on Spring library, defined in the org.springframework.web.multipart.MultipartFile package. Out of the box, Spring provides MultipartResolvers for use with Commons FileUpload (http://jakarta.apache.org/commons/fileupload) and COS FileUpload (http://www.servlets.com/cos). In this post, it shows you how to handle file upload in Spring MVC web application.

By default, no multipart handling will be done by Spring. You will have to enable it yourself by adding a multipart resolver to the web application’s context. After you have done that, each request will be inspected to see if it contains a multipart. If no multipart is found, the request will continue as expected. However, if a multipart is found in the request, the MultipartResolver that has been declared in your context will be used. After that, the multipart attribute in your request will be treated like any other attribute.

Using the MultipartResolver

The CommonsMultipartResolver is a common MultipartResolver implementation, which use the Apache commons upload library to handle the file upload in a form. To use CommonsMultipartResolver to handle the file upload, you need to get the commons-fileupload.jar andcommons-io.jar libraries.

The following example shows how to use the CommonsMultipartResolver:

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="100000"/>
</bean>

This is an example using the CosMultipartResolver:

<bean id="multipartResolver" class="org.springframework.web.multipart.cos.CosMultipartResolver">

    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="100000"/>
</bean>

Model

Create a MultipartFile variable to store the uploaded file. Alternatively, you can use the byte[] to store it, but I more prefer to use the MultipartFile, because it can get the uploaded file detail (file name, file size …) so easily.

import org.springframework.web.multipart.MultipartFile;

public class FileUpload{

	MultipartFile file;
	//other properties
	//getter and setter methods

}

File Upload Controller

Extends the SimpleFormController and handle the file upload form like a normal form.

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

// dont forget to import FileUpload
import FileUpload;

public class FileUploadController extends SimpleFormController{

	public FileUploadController(){
		setCommandClass(FileUpload.class);
		setCommandName("fileUploadForm");
	}

	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {

		FileUpload file = (FileUpload)command;

		MultipartFile multipartFile = file.getFile();

		String fileName="";

		if(multipartFile!=null){
			fileName = multipartFile.getOriginalFilename();
			//do whatever you want
		}

		return new ModelAndView("FileUploadSuccess","fileName",fileName);
	}
}

File Upload Validation

A simple validation for the uploaded file, display the error message if the uploaded file is empty.

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import yourpacakge.FileUpload;

public class FileUploadValidator implements Validator{

	@Override
	public boolean supports(Class clazz) {
		//just validate the FileUpload instances
		return FileUpload.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {

		FileUpload file = (FileUpload)target;

		if(file.getFile().getSize()==0){
			errors.rejectValue("file", "required.fileUpload");
		}
	}
}

Don’t forget to add these line in file message.properties:

required.fileUpload = Please select a file!

View Page

The Spring’s form tag didn’t comes with any file upload tag (that’s weird). So, you have to declared the pure HTML file tag manually. Furthermore, in the Spring’s form, define the form encoding attributeenctype=”multipart/form-data”, so that the browser will know how to handle the multipart file. In last, wrap some Spring’s form error tag to display the error message.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}

.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>

<body>
	<h2>Spring MVC file upload example</h2>

	<form:form method="POST" commandName="fileUploadForm"
		enctype="multipart/form-data">

		<form:errors path="*" cssClass="errorblock" element="div" />

		Please select a file to upload : <input type="file" name="file" />
		<input type="submit" value="upload" />
		<span><form:errors path="file" cssClass="error" />
		</span>

	</form:form>

</body>
</html>

If the file is uploaded successfully, display the uploaded file name.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<html>
<body>
	<h2>Spring MVC file upload example</h2>

	FileName : "
	<strong> ${fileName} </strong>" - Uploaded Successful.

</body>
</html>

Spring Configuration

Register CommonsMultipartResolver to tell Spring to use commons-upload library to handle the file upload form. The rest is just normal bean declaration.

<bean id="multipartResolver"
	class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

<bean class="yourpackage.FileUploadController">
	<property name="formView" value="FileUploadForm" />
	<property name="successView" value="FileUploadSuccess" />

	<!-- Map a validator -->
	<property name="validator">
		<bean class="yourpackage.FileUploadValidator" />
	</property>
</bean>