Spring 4 multiple files upload example with/without using @ModelAttribute

In this tutorial, let us see that how to upload multiple files from client to server using Spring 4 with/without  the use of annotation ModelAttribute.

Jars used in this tutorial.

1. Spring 4
2. jstl

Additional Jars required  to handle parsing of uploaded files.

1. Commons-FileUpload 1.3.1 or above
2. Commons-IO 2.2 or above

Add the above jars to your class path if you don’t have already.

Maven Dependencies for the above Jars are given below

<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.1</version>
</dependency>

<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.2</version>
</dependency> 

Please find the Project Structure & Jars used in this project.

Spring Multiple file upload Project Structure

Jars

 

Let us create a example Spring project called SpringMultipleFileUpload. For creating Spring project, you can visit my earlier tutorial Create spring web project example.

Steps to upload multiple files.

Step 1: Design a web form for uploading a file. You need to set the encoding type of form to “multipart/form-data” and specify the HTTP method as “post”. JSP code is given below. JSP includes the java script code to add file input dialog box dynamically.

With the use of annotation ModelAttribute:

MultipleFileUploadMA.jsp (View A)

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

<script>

	function AddMoreFile(tableID) {
	    var table = document.getElementById(tableID);
	    var rowCount = table.rows.length;
	    var row = table.insertRow(rowCount);
	    var col1 = row.insertCell(0);
	    var colInput = document.createElement("input");
	    colInput.type = "file";
	    colInput.name="files["+(rowCount)+"]";
	    col1.appendChild(colInput);
	}

  </script> 

<h1>Spring Multiple File Upload Example @ModelAttribute</h1>

<form:form method="post" action="uploadMultipleFilesMA.do"  modelAttribute="multipleFileUploadForm"   enctype="multipart/form-data">

    <p>Select files to upload. Click on Add More button to add more files.</p>

    <TABLE id="fuTable"  border="1">
    <TR>
        <TD> <input name="files[0]" type="file"></TD>
    </TR>

    </TABLE>
    <br>    <input  type="button" value="Add More File"  onclick="AddMoreFile('fuTable')">
    <input type="submit" value="Upload">

</form:form> 

Without using @ModelAttribute:

MultipleFileUpload.jsp (View B)

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

<script>

function AddMoreFile(tableID) {
    var table = document.getElementById(tableID);
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);
    var col1 = row.insertCell(0);
    var colInput = document.createElement("input");
    colInput.type = "file";
    colInput.name="files";
    col1.appendChild(colInput);
}

</script>

<h1>Spring Multiple File Upload example</h1>

<form:form method="post" action="uploadMultipleFiles.do"  enctype="multipart/form-data">

    <p>Select files to upload. Click Add More button to add more files.</p>

    <TABLE id="fuTable"  border="1">
    <TR>
        <TD> <input name="files" type="file"></TD>
    </TR>

    </TABLE>

    <br>   <input  type="button" value="Add More File"  onclick="AddMoreFile('fuTable')">
    <input type="submit" value="Upload">
</form:form> 

Please note that File names are mentioned as arrays explicitly in the First JSP, where as file names are not mentioned as arrays explicitly in the second JSP.

Step 2 : Now let us write controller class for uploading. The controller class contains methods for uploading multiple files with / without using ModelAttribute annotation.

Methods for uploading Multiple Files with the use of annotation ModelAttribute.

1. loadMultipleFileUploadMA – to load MultipleFileUploadMA form i.e. MultipleFileUploadMA.jsp

2. handleFileUploadMA – to process multiple file upload with @ModelAttribute annotation. This annotation is used as an argument of this method which binds form fields to an model object (in this example, model object is multipleFileUploadForm)

Methods for uploading Multiple Files without the use of @ModelAttribute.

1. loadMultipleFileUpload – to load MultipleFileUpload form i.e. MultipleFileUpload.jsp

2. handleFileUpload – to process multiple file upload.

The complete java code for the controller is given below.

MultipleFileUploadController.java

package net.javaonline.spring.fileupload.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;

import net.javaonline.spring.fileupload.form.MultipleFileUploadForm;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class MultipleFileUploadController {

 @RequestMapping(value="/loadMultipleFileUploadMA")
 public String loadMultipleFileUploadMA(Map<String, Object> model) {
     return "MultipleFileUploadMA";
 }

 //Using @ModelAttribute as method parameter.

@RequestMapping(value="/uploadMultipleFilesMA", method=RequestMethod.POST)
public String handleFileUploadMA(@ModelAttribute("multipleFileUploadForm") MultipleFileUploadForm multipleFileUploadForm, Model model){

	List<MultipartFile> files=multipleFileUploadForm.getFiles();   // Storing all Multipart files in a List

	System.out.println(" Files count " + files.size());

        try {
        	String filePath="c:/temp/kk/";
        	for (int i=0;i<files.size();i++)
        		files.get(i).transferTo(new File(filePath+files.get(i).getOriginalFilename()));  // Transfer the content of each file to  the file Path (i.e. c:\temp\kk)
        } catch (Exception e) {
            return "Error While uploading your files " +  e.getMessage();
        }

        model.addAttribute("files", files);
        return "result";
    } 

@RequestMapping(value="/loadMultipleFileUpload")
public String loadMultipleFileUpload(Map<String, Object> model) {
    return "MultipleFileUpload";
}

// Without Using @ModelAttribute

    @RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST)
    public @ResponseBody String handleFileUpload( @RequestParam("files") MultipartFile files[]){
            try {
            	String filePath="c:/temp/kk/";
            	StringBuffer result=new StringBuffer();
            	byte[] bytes=null;
            	result.append("Uploading of File(s) ");

            	for (int i=0;i<files.length;i++) {
                    if (!files[i].isEmpty()) {
		                bytes = files[i].getBytes();
		                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath+files[i].getOriginalFilename())));
		                stream.write(bytes);
		                stream.close();

		               result.append(files[i].getOriginalFilename() + " Ok. ") ;
                    }
                    else
                    	result.append( files[i].getOriginalFilename() + " Failed. ");

            }
                return result.toString();

            } catch (Exception e) {
                return "Error Occured while uploading files." + " => " + e.getMessage();
            }

    } 

}

Step 3:  Create Model class  for Multiple File upload (Applicable only when using @ModelAttribute)

Create Model class for mapping multiple files of type org.springframework.web.multipart.MultipartFile. Spring MultipartFile represents the uploaded file received by multipart request. It provides various methods to do various tasks such as to get the original file name, size of the file, content of the file as bytes, to transfer the file contents to the given destination file, etc…

MultipleFileUploadForm.java

package net.javaonline.spring.fileupload.form;

import java.util.List;

import org.springframework.web.multipart.MultipartFile;

public class MultipleFileUploadForm {

    private List<MultipartFile> files;

		public List<MultipartFile> getFiles() {
			return files;
		}

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

} 

Step 4: Spring Configuration at FileUpload-Context.xml

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="net.javaonline.spring.fileupload.controller" />

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

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/Pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

</beans>

Please note that a special bean multipartResolver is created for the class CommonsMultipartResolver that handles file upload with the use of Apache Commons Fileupload

Step 5 : web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

  <servlet>
    <servlet-name>FileUpload</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/FileUpload-Context.xml</param-value>
      </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>FileUpload</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

</web-app> 

Step 6: Create view (result.jsp )

To display the name of the files uploaded using loop.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring Multiple File Upload Result</title>
</head>
<body>
    <p>Uploading of file(s)
        <c:forEach items="${files}" var="file">
            ${file.getOriginalFilename()},
        </c:forEach>
   are successful </p>
</body>
</html>

Now run the project by using the following urls

http://localhost:8080/SpringMultipleFileUpload/loadMultipleFileUpload.do

Spring file uploadSpring file upload 1

 

Result :

Spring file upload result

Using @ModelAttribute

http://localhost:8080/SpringMultipleFileUpload/loadMultipleFileUploadMA.do

Spring file upload MA

Spring file upload MA1

Result:

Spring file upload result MA

Note : Files are uploaded in the path  c:/temp/kk

You can download the above example project at Spring Multiple File Download 

 

Reference :  Uploading FIles

You may also like

Leave a Reply