Spring MVC 4 File Upload Example using Servlet 3 MultiPartConfigElement

In this post we will implement Single and Multiple Fileupload functionality using Spring MultipartResolver implementaion StandardServletMultipartResolver in Servlet 3 environments. Spring provides build-in multipart support to handle file uploads in a web application.

Spring4MVCFileUploadMultipartConfigElementExample_img8


Spring4MVCFileUploadMultipartConfigElementExample_img3

Short Overview

Previous post showed file upload using CommonsMultipartResolver. That implementations works well even in Servlet 3.0 environment. In this post, we will implement same example again, but using Servlet 3.0 specific javax.servlet.MultipartConfigElement

In order to activate Multipart support with Spring in Servlet 3.0 environment, you need to do following

1. Add StandardServletMultipartResolver Bean to your Spring Configuration.It’s a standard implementation of the MultipartResolver interface, based on the Servlet 3.0 javax.servlet.http.Part API.

2. Enable MultiParsing in Servlet 3.0 environments. To do that, You have several choices to choose from.

  • Choice A. Set javax.servlet.MultipartConfigElement in programmatic Servlet registration. MultipartConfigElement is simply Java Class representation of an javax.servlet.annotation.MultipartConfig annotation value (as described in choice c). This post will focus specially on this choice.

  • Choice B. If you are using XML based configuration, you can declare multipart-config section under servlet configuration in web.xml, as shown below:

        <servlet>
            <servlet-name>SpringDispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <multipart-config>
                <location>/tmp</location>
                <max-file-size>5242880</max-file-size><!--5MB-->
                <max-request-size>20971520</max-request-size><!--20MB-->
                <file-size-threshold>0</file-size-threshold>
            </multipart-config>
        </servlet>
    
  • Choice C. You can create a custom Servlet and annotate it with javax.servlet.annotation.MultipartConfig annotation as shown below:

    @WebServlet(name = "fileUploadServlet", urlPatterns = {"/upload"})
    @MultipartConfig(location=/tmp,
                     fileSizeThreshold=0,    
                     maxFileSize=5242880,       // 5 MB
                     maxRequestSize=20971520)   // 20 MB
    public class FileUploadServlet extends HttpServlet {
      
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //handle file upload
        }      
    

That being said, we will focus on Choice A in this example.


Complete Example



Following technologies being used:

  • Spring 4.2.0.RELEASE
  • validation-api 1.1.0.Final
  • Bootstrap v3.3.2
  • Maven 3
  • JDK 1.7
  • Tomcat 8.0.21
  • Eclipse JUNO Service Release 2

Let’s begin.

Project Structure

Spring4MVCFileUploadMultipartConfigElementExample_img1

Declare dependencies in 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.websystique.springmvc</groupId>
	<artifactId>Spring4MVCFileUploadMultipartResolverExample</artifactId>
	<packaging>war</packaging>
	<version>1.0.0</version>
	<name>Spring4MVCFileUploadMultipartConfigElementExample Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<properties>
		<springframework.version>4.2.0.RELEASE</springframework.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${springframework.version}</version>
		</dependency>

		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>


	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.2</version>
					<configuration>
						<source>1.7</source>
						<target>1.7</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<warName>Spring4MVCFileUploadMultipartConfigElementExample</warName>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>

		<finalName>Spring4MVCFileUploadMultipartConfigElementExample</finalName>
	</build>
</project>
  

Programmatic Registration of MultiPartConfigElement

This registration provides opportunity to set specific properties like maximum filesize, request size, location and threshold after which file will be stored temporarily on disk during upload operation.

package com.websystique.springmvc.configuration;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class HelloWorldInitializer extends
		AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] { HelloWorldConfiguration.class };
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return null;
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

	@Override
	protected void customizeRegistration(ServletRegistration.Dynamic registration) {
		registration.setMultipartConfig(getMultipartConfigElement());
	}

	private MultipartConfigElement getMultipartConfigElement() {
		MultipartConfigElement multipartConfigElement = new MultipartConfigElement(	LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
		return multipartConfigElement;
	}

	private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored

	private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
														// Beyond that size spring will throw exception.
	private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
	
	private static final int FILE_SIZE_THRESHOLD = 0; // Size threshold after which files will be written to disk
}

Notice how we have overridden function customizeRegistration in order to register the required MultiPartConfigElement to DispatcherServlet.

Create Configuration

Configure StandardServletMultipartResolver Bean. It’s a standard implementation of the MultipartResolver interface, based on the Servlet 3.0 javax.servlet.http.Part API.

package com.websystique.springmvc.configuration;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springmvc")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {

	@Bean(name = "multipartResolver")
	public StandardServletMultipartResolver resolver() {
		return new StandardServletMultipartResolver();
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setViewClass(JstlView.class);
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		registry.viewResolver(viewResolver);
	}

	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasename("messages");
		return messageSource;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations( "/static/");
	}

}

This Configuration class in XML format will be:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 
    <context:component-scan base-package="com.websystique.springmvc" />
    <mvc:annotation-driven />

    <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>

    <mvc:resources mapping="/static/**" location="/static/" />
    <mvc:default-servlet-handler />


    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename">
            <value>messages</value>
        </property>
    </bean>


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 
</beans>

Create Model classes

Spring provides org.springframework.web.multipart.MultipartFile which is a representation of an uploaded file received in a multipart request. It provides handy methods like getName(), getContentType(), getBytes(), getInputStream() etc.. which make life bit easier while retrieving information about file being uploaded.

Let’s write a wrapper class to further simply it’s usage in our application


package com.websystique.springmvc.model;

import org.springframework.web.multipart.MultipartFile;

public class FileBucket {

	MultipartFile file;
	
	public MultipartFile getFile() {
		return file;
	}

	public void setFile(MultipartFile file) {
		this.file = file;
	}
}

To demonstrate Multiple uploads example as well, let’s create one more wrapper class.

package com.websystique.springmvc.model;

import java.util.ArrayList;
import java.util.List;

public class MultiFileBucket {

	List<FileBucket> files = new ArrayList<FileBucket>();
	
	public MultiFileBucket(){
		files.add(new FileBucket());
		files.add(new FileBucket());
		files.add(new FileBucket());
	}
	
	public List<FileBucket> getFiles() {
		return files;
	}

	public void setFiles(List<FileBucket> files) {
		this.files = files;
	}
}

This class can handle up to 3 file uploads.

Create Controller

package com.websystique.springmvc.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import com.websystique.springmvc.model.FileBucket;
import com.websystique.springmvc.model.MultiFileBucket;
import com.websystique.springmvc.util.FileValidator;
import com.websystique.springmvc.util.MultiFileValidator;

@Controller
public class FileUploadController {

	private static String UPLOAD_LOCATION="C:/mytemp/";

	@Autowired
	FileValidator fileValidator;

	@Autowired
	MultiFileValidator multiFileValidator;

	@InitBinder("fileBucket")
	protected void initBinderFileBucket(WebDataBinder binder) {
		binder.setValidator(fileValidator);
	}

	@InitBinder("multiFileBucket")
	protected void initBinderMultiFileBucket(WebDataBinder binder) {
		binder.setValidator(multiFileValidator);
	}

	@RequestMapping(value = { "/", "/welcome" }, method = RequestMethod.GET)
	public String getHomePage(ModelMap model) {
		return "welcome";
	}

	@RequestMapping(value = "/singleUpload", method = RequestMethod.GET)
	public String getSingleUploadPage(ModelMap model) {
		FileBucket fileModel = new FileBucket();
		model.addAttribute("fileBucket", fileModel);
		return "singleFileUploader";
	}

	@RequestMapping(value = "/singleUpload", method = RequestMethod.POST)
	public String singleFileUpload(@Valid FileBucket fileBucket,
			BindingResult result, ModelMap model) throws IOException {

		if (result.hasErrors()) {
			System.out.println("validation errors");
			return "singleFileUploader";
		} else {
			System.out.println("Fetching file");
			MultipartFile multipartFile = fileBucket.getFile();

			// Now do something with file...
			FileCopyUtils.copy(fileBucket.getFile().getBytes(), new File( UPLOAD_LOCATION + fileBucket.getFile().getOriginalFilename()));
			String fileName = multipartFile.getOriginalFilename();
			model.addAttribute("fileName", fileName);
			return "success";
		}
	}

	@RequestMapping(value = "/multiUpload", method = RequestMethod.GET)
	public String getMultiUploadPage(ModelMap model) {
		MultiFileBucket filesModel = new MultiFileBucket();
		model.addAttribute("multiFileBucket", filesModel);
		return "multiFileUploader";
	}

	@RequestMapping(value = "/multiUpload", method = RequestMethod.POST)
	public String multiFileUpload(@Valid MultiFileBucket multiFileBucket,
			BindingResult result, ModelMap model) throws IOException {

		if (result.hasErrors()) {
			System.out.println("validation errors in multi upload");
			return "multiFileUploader";
		} else {
			System.out.println("Fetching files");
			List<String> fileNames = new ArrayList<String>();
			// Now do something with file...
			for (FileBucket bucket : multiFileBucket.getFiles()) {
				FileCopyUtils.copy(bucket.getFile().getBytes(), new File(UPLOAD_LOCATION + bucket.getFile().getOriginalFilename()));
				fileNames.add(bucket.getFile().getOriginalFilename());
			}

			model.addAttribute("fileNames", fileNames);
			return "multiSuccess";
		}
	}

}

Above controller is fairly trivial. It handles GET and POST request for file upload view. Once file is selected from File picker and user clicked on upload, we are simply creating a new file with the same name and bytes content as original file, copying the bytes from original file. For that we are using Spring FileCopyUtils utility class to copy stream from source to destination. In this example, we have specified destination as C:/mytemp folder, all files will end up in this folder.

Create Validators classes

We are using some Validators to verify that user have indeed selected a file to be uploaded. They are shown below.

package com.websystique.springmvc.util;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.websystique.springmvc.model.FileBucket;

@Component
public class FileValidator implements Validator {
	
	public boolean supports(Class<?> clazz) {
		return FileBucket.class.isAssignableFrom(clazz);
	}

	public void validate(Object obj, Errors errors) {
		FileBucket file = (FileBucket) obj;
		
		if(file.getFile()!=null){
			if (file.getFile().getSize() == 0) {
				errors.rejectValue("file", "missing.file");
			}
		}
	}
}
package com.websystique.springmvc.util;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.websystique.springmvc.model.FileBucket;
import com.websystique.springmvc.model.MultiFileBucket;

@Component
public class MultiFileValidator implements Validator {
	
	public boolean supports(Class<?> clazz) {
		return MultiFileBucket.class.isAssignableFrom(clazz);
	}

	public void validate(Object obj, Errors errors) {
		MultiFileBucket multiBucket = (MultiFileBucket) obj;
		
		int index=0;
		
		for(FileBucket file : multiBucket.getFiles()){
			if(file.getFile()!=null){
				if (file.getFile().getSize() == 0) {
					errors.rejectValue("files["+index+"].file", "missing.file");
				}
			}
			index++;
		}
		
	}
}

messages.properties

missing.file= Please select a file.

Create Views

singleFileUploader.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>Spring 4 MVC File Upload Example</title>
	<link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet" type="text/css"></link>
	<link href="<c:url value='/static/css/app.css' />" rel="stylesheet" type="text/css"></link>
</head>
<body> 

	<div class="form-container">
		<h1>Spring 4 MVC File Upload Example </h1>
		<form:form method="POST" modelAttribute="fileBucket" enctype="multipart/form-data" class="form-horizontal">
		
			<div class="row">
				<div class="form-group col-md-12">
					<label class="col-md-3 control-lable" for="file">Upload a file</label>
					<div class="col-md-7">
						<form:input type="file" path="file" id="file" class="form-control input-sm"/>
						<div class="has-error">
							<form:errors path="file" class="help-inline"/>
						</div>
					</div>
				</div>
			</div>
	
			<div class="row">
				<div class="form-actions floatRight">
					<input type="submit" value="Upload" class="btn btn-primary btn-sm">
				</div>
			</div>
		</form:form>
		<a href="<c:url value='/welcome' />">Home</a>
	</div>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>File Upload Success</title>
	<link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>
	<link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link>
</head>
<body>
	<div class="success">
		File  <strong>${fileName}</strong> uploaded successfully.
		<br/><br/>
		<a href="<c:url value='/welcome' />">Home</a>	
	</div>
</body>
</html>

multiFileUploader.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>Spring 4 MVC File Multi Upload Example</title>
	<link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet" type="text/css"></link>
	<link href="<c:url value='/static/css/app.css' />" rel="stylesheet" type="text/css"></link>
</head>
<body> 

	<div class="form-container">
		<h1>Spring 4 MVC Multi File Upload Example </h1>
		<form:form method="POST" modelAttribute="multiFileBucket" enctype="multipart/form-data" class="form-horizontal">
		
			<c:forEach var="v" varStatus="vs" items="${multiFileBucket.files}">
				<form:input type="file" path="files[${vs.index}].file" id="files[${vs.index}].file" class="form-control input-sm"/>
				<div class="has-error">
					<form:errors path="files[${vs.index}].file" class="help-inline"/>
				</div>
			</c:forEach>
			<br/>
			<div class="row">
				<div class="form-actions floatRight">
					<input type="submit" value="Upload" class="btn btn-primary btn-sm">
				</div>
			</div>
		</form:form>
		
		<br/>
		<a href="<c:url value='/welcome' />">Home</a>
	</div>
</body>
</html>

multiSuccess.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>File Upload Success</title>
	<link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>
	<link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link>
</head>
<body>
	<div class="success">
			<c:forEach var="fileName" items="${fileNames}">
				File  <strong>${fileName}</strong> uploaded successfully<br/>
			</c:forEach>
			<br/>
		<a href="<c:url value='/welcome' />">Home</a>
	</div>
</body>
</html>

welcome.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>Spring 4 MVC File Upload Example</title>
	<link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet"></link>
	<link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link>
</head>
<body>
	<div class="form-container">
		<h1>Welcome to FileUploader Example</h1>
		
		Click on below links to see FileUpload in action.<br/><br/>
		
		<a href="<c:url value='/singleUpload' />">Single File Upload</a>  OR  <a href="<c:url value='multiUpload' />">Multi File Upload</a>
	</div> 
</body>
</html>

Build, Deploy & Run Application

Now build the war (either by eclipse as was mentioned in previous tutorials) or via maven command line( mvn clean install). Deploy the war to a Servlet 3.0 container . Since here i am using Tomcat, i will simply put this war file into tomcat webapps folder and click on start.bat inside tomcat/bin directory.

Open browser and browse at http://localhost:8080/Spring4MVCFileUploadMultipartConfigElementExample/

Spring4MVCFileUploadMultipartConfigElementExample_img2

Now click on Single File Upload link.

Spring4MVCFileUploadMultipartConfigElementExample_img3

click on Upload, without selecting a file. It should show validation failure message.

Spring4MVCFileUploadMultipartConfigElementExample_img4

Click on Choose File.

Spring4MVCFileUploadMultipartConfigElementExample_img5

File picker should be shown. Select a file.

Spring4MVCFileUploadMultipartConfigElementExample_img6

Clink on Upload. File uploaded.

Spring4MVCFileUploadMultipartConfigElementExample_img7

You can check Upload folder [C:/mytemp] for uploaded file.

Now Go back, and clink on multi upload link this time.

Spring4MVCFileUploadMultipartConfigElementExample_img8

Click on upload without any file selection, should receive validation error.

Spring4MVCFileUploadMultipartConfigElementExample_img9

Select files.

Spring4MVCFileUploadMultipartConfigElementExample_img10

Clink on Upload. All selected files should be uploaded.

Spring4MVCFileUploadMultipartConfigElementExample_img11

Finally check the storage folder [C:/mytemp].

Spring4MVCFileUploadMultipartConfigElementExample_img12

That’s it. Next post introduces File Download using Spring MVC 4.

Download Source Code



References

If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help me improve further our learning process.

If you appreciate the effort I have put in this learning site, help me improve the visibility of this site towards global audience by sharing and linking this site from within and beyond your network. You & your friends can always link my site from your site on www.websystique.com, and share the learning.

After all, we are here to learn together, aren’t we?

  • katscoding

    Okay I would like to understand how clicking the submit button triggers the Controller. My goal is to add a text input field to the form and this would be a parameter to the post request. on SingleUpload. But I don’t know how that data would get passed back

    • websystique

      Start from JSP [SingleFileuploader.jsp]. There, the ‘upload’ button is actually an input of type ‘submit’ means it will submit the form it is in. Shown below is the form:

      Now when you click on the ‘upload’ button, above form gets submitted with HTTP method POST and the URL in the address bar at that moment [.../singleUpload]. In the controller [FileUploadController] we have the mapping for this URL, specific to HTTP methods. In that method we process the request [call service, upload file, blabla..] and then eventually return a view name which gets resolved [thanks to configured view resolver] and displays that view at the end of request processing. I hope it is clear for you.

  • Yiwei Sun

    Great job.
    Thanks a lot.
    But in my environment, for multiFileUpload:
    multiFileUploader.jsp

    does not work, I got HTTP 500 errors.

    I have to change that line into

    according to: http://docs.oracle.com/javaee/5/jstl/1.1/docs/api/javax/servlet/jsp/jstl/core/LoopTagStatus.html

    • websystique

      it is more of a matter of using property vs getter/setter.Anyway, thanks for pointing it out.

  • AlieneilA

    Hi, thanks so much for this.
    I am trying to use this in my project, but unfortunately I get an error because the directory is not valid. I tried to look up a way to handle this, but I cannot find it. Could you please give me some leads on this?
    Thanks in advance!

    • websystique

      Hi, If you are referring to project directory, you may want to look at Creating Maven project with Eclipse.If you meant the directory where the file gets upload, in this post it is c:/mytemp. Let me know if i misunderstood you.

      • AlieneilA

        Hi, thanks for your reaction! I have managed it now and got it to work properly! Thanks again for putting up these great posts, I’ve found many of them really helpfull!

  • Waqas Baig

    Hi,
    I need to display uploaded file name in
    How can I do it?
    Regards,
    Waqas

    • websystique

      Sorry i missed it. Concerning the question, input of type “file” itself shows the file name once a file has been chosen.

      • Waqas Baig

        Websystique: I meant to say that, file already uploaded on server, then on the edit record data filled in fields and I need to show the filename on
        Is it possible?
        Regards,
        Waqas Baig.

  • NathanR

    Hi,
    First of all thanks for this article.
    Can you suggest a way to handle the max file size exception limit?

    I’d like to notify the user, in the same jsp, that the file is too large before he uploads…

  • Ishmam

    If i want to upload file in project’s directory,than what should i do???

  • FaisalHyder

    Hi there, :) can you make it for MongoDB.?
    thanks once again, your tutorials are really helping to start the things and then do some hard work and hurray :D

  • Pingback: Spring MVC 4 FileUpload-Download Hibernate+MySQL Example - WebSystique()

  • Pingback: Spring MVC 4 File Upload Example using Commons fileupload - WebSystique()