Spring 4 MVC Multiple File Upload Example

December 26, 2015 | 4981 views | Comments

Upload multiple files with Spring 4 MVC Framework. Restrict file types allowed to be uploaded and set the approved max file upload size.

 

Built and tested with the following:

  • Eclipse Juno IDE
  • Apache Tomcat 7.0.47
  • JDK 1.7.0
  • Maven 3.0.4
  • Spring Web-MVC Framework 4.2.2
    • Configuration: XML
    • Url Mapping: Annotation
  • Jackson JSON 2.6.3
  • Apache Commons FileUpload 1.3.1
  • jQuery 1.11.3
  • BootStrap 3.3.5
  • ccFileUpload (jQuery File Upload Plugin)

 

Task: Create a Spring WebMVC 4 application that will have the ability to upload multiple files, making use ccFileUpload - a jQuery File Upload Plugin, that will return a message in JSON format.


Summary

  • Step 1. Create a new Maven Project.
  • Step 2. Edit pom.xml file.
  • Step 3. Edit web.xml file.
  • Step 4. Create spring-servlet.xml file.
  • Step 5. Create the template file.
  • Step 6. Create the File Upload Class.
  • Step 7. Create the Response Class.
  • Step 8. Copy the resource files.
  • Step 9. Create the Controller Class.

Highlights

Add Dependencies (pom.xml).

Spring Framework.

<!-- Spring Framework -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.2.2.RELEASE</version>
</dependency>

Read more about Spring 4 MVC Hello World Annotation Example

Apache Commons FileUpload.

<!-- Apache Commons FileUpload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

Read more about Spring 4 MVC File Upload Example

Jackson.

<!-- Jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.3</version>
</dependency>

Read more about Spring 4 MVC JSON Hello World Annotation Example

 

Settings (spring-servlet.xml)

multipartResolver.

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

Map the resources outside of WEB-INF so it can be viewed publicly.

<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />

 

Controller Class (Main.java).

Returns a message in JSON format.

@RequestMapping(value="/upload", method=RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public Response handleFileUpload(@RequestParam("file") MultipartFile[] file) {

        List<String> result = new ArrayList<String>();
        for (int i = 0; i < file.length; i++) {
            /**
             * do whatever to file[i] - hint... save!
             */

            //add a message for file[i]
            //result.add();
        }

        return new Response(result);
    }

Read more about Spring 4 MVC File Upload Example

 

JSON message handler Class (Response.java).

package com.consistentcoder.models;

import java.util.List;

public class Response {
    private List<String> response;
    
    public Response(List<String> message){
        this.response = message;
    }

    /**
     * Getter/Setter omitted...
     */
}

Read more about Spring 4 MVC JSON Hello World Annotation Example


Let's begin!


Step 1. Create a new Maven Project.

Use the following details when setting up the new Maven Project:

  • Group Id: com.consistentcoder
  • Artifact Id: spring-4-multiple-file-upload-example
  • Name: spring 4 multiple file upload example

Tutorials:
Create a New Maven Project in Eclipse
Configure Run on Server option on a Maven Project on Eclipse IDE

Your Maven Project Structure would look something like the image below.

 

Step 2. Edit pom.xml file.

On the file "pom.xml", put the following code inside it.

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.consistentcoder</groupId>
    <artifactId>spring-4-multiple-file-upload-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>spring 4 multiple file upload example</name>
    
    <dependencies>
        <!-- Spring Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>
        
        <!-- Apache Commons FileUpload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        
        <!-- Jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.3</version>
        </dependency>
    </dependencies>
</project>

/pom.xml

 

Step 3. Edit web.xml file.

Put the code below inside "web.xml".

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>spring-4-multiple-file-upload-example</display-name>

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

/src/main/webapp/WEB-INF/web.xml

 

Step 4. Create spring-servlet.xml file.

Create another xml file, name it "spring-servlet.xml" on the same folder where "web.xml" is located.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

    <context:component-scan base-package="com.consistentcoder.controllers" />
    <mvc:annotation-driven />
    <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />

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

/src/main/webapp/WEB-INF/spring-servlet.xml

 

Step 5. Create the template file.

Create a new folder "jsp" inside "WEB-INF". Then inside that newly created folder, create a new jsp file ("index.jsp") that will contain the code below.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 4 Multiple File Example</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
    <link rel="stylesheet" href="resources/css/ccFileUpload.css">
    <style type="text/css">
        body{ margin:50px 0px; }
        .thumbnail{ padding:0px; }
        .stageParent{ background:#fff; border:3px dashed #444; border-radius:5px; padding:10px; }
        .stage{ min-height:220px; max-height:400px; overflow-y:auto; }
    </style>
</head>
<body>
    <div class="container">
        <div class="col-xs-12 text-center text-primary">
            <h1>${ message }</h1>
        </div>
        <div class="col-xs-12"> </div>
        <form method="post" enctype="multipart/form-data" action="">
        <div class="col-xs-12">
            <div id="consistentCoder" class="text-center"></div>
        </div>
        <div class="col-xs-12">
            <div class="label label-info pull-right"><span class="countMe">0</span> files uploaded.</div>
        </div>
        <div class="col-xs-12"> </div>
        <div class="col-xs-12 stageParent">
            <div id="stage" class="stage"></div>
        </div>
        </form>
        <div class="col-xs-12"> </div>
        <div id="response" class="text-center"></div>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="resources/js/ccFileUpload.js"></script>
    <script>
        $(document).ready(function(){
            var options = {
                    'name':'file',
                    'uploadUrl':'upload',
                    'sync':false,
                    'previews':'stage',
                    'response':'response',
                    'counter':'countMe',
                    'columnClass':'col-md-3 text-center',
                    'allowedFiles':['gif','png','jpg','jpeg','xlsx','.psd'],
                    'allowedPreviews':['jpg','jpeg'],
                    'animSpeed':'fast'
                  };
            $("#consistentCoder").ccFileUpload(options);
        });
    </script>
</body>
</html>

/src/main/webapp/WEB-INF/jsp/index.jsp

 

Maven Project Structure Update.

 

Step 6. Create the File Upload Class.

Create a new package ("com.consistentcoder.models"). Then create a new class inside it ("FileUpload").

Tutorials:
Create a New Package on Eclipse IDE
Create a New JAVA Class on Eclipse IDE

Code of FileUpload.java Class.

package com.consistentcoder.models;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.springframework.web.multipart.MultipartFile;

public class FileUpload {
    private static final String[] ALLOWED_FILE_TYPES = {"image/jpeg", "image/jpg", "image/gif"};
    private static final Long MAX_FILE_SIZE = 1048576L; //1MB
    private static final String UPLOAD_FILE_PATH = "/opt/images/";
    
    public String process(MultipartFile file) {
        if (!file.isEmpty()) {
            String contentType = file.getContentType().toString().toLowerCase();
            if (isValidContentType(contentType)) {
                if (belowMaxFileSize(file.getSize())) {
                    String newFile = UPLOAD_FILE_PATH + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(newFile));
                        return "You have successfully uploaded " + file.getOriginalFilename() + "!";
                    } catch (IllegalStateException e) {
                        return "There was an error uploading " + file.getOriginalFilename() + " => " + e.getMessage();
                    } catch (IOException e) {
                        return "There was an error uploading " + file.getOriginalFilename() + " => " + e.getMessage();
                    }
                } else {
                    return "Error. " + file.getOriginalFilename() + " file size (" + file.getSize() + ") exceeds " + MAX_FILE_SIZE + " limit.";
                }
            } else {
                return "Error. " + contentType + " is not a valid content type.";
            }
        } else {
            return "Error. No file choosen.";
        }
    }
    
    private Boolean isValidContentType(String contentType) {
        if (!Arrays.asList(ALLOWED_FILE_TYPES).contains(contentType)) {
            return false;
        }
        
        return true;
    }
    
    private Boolean belowMaxFileSize(Long fileSize) {
        if (fileSize > MAX_FILE_SIZE) {
            return false;
        }
        
        return true;
    }
}

/src/main/java/com/consistentcoder/models/FileUpload.java

 

Step 7. Create the Response Class.

Inside "com.consistentcoder.models", create a new Class Response, then put the following code inside it.

package com.consistentcoder.models;

import java.util.List;

public class Response {
    private List<String> response;
    
    public Response(List<String> message){
        this.response = message;
    }

    public List<String> getResponse() {
        return response;
    }

    public void setResponse(List<String> response) {
        this.response = response;
    }

}

/src/main/java/com/consistentcoder/models/Response.java

 

Step 8. Copy the resource files.

Inside "WEB-INF", create a new folder resources, then inside it create two new folders "jsp" and "css".

 

Go to https://github.com/ConsistentCoder/ccFileUpload, copy ccFileUpload.css and save it inside "WEB-INF/resources/css/"

/src/main/webapp/WEB-INF/resources/css/ccFileUpload.css

 

Go to https://github.com/ConsistentCoder/ccFileUpload, copy ccFileUpload.js and save it inside "WEB-INF/resources/js"/

/src/main/webapp/WEB-INF/resources/js/ccFileUpload.js

 

Updated Maven Project Structure.

 

Step 9. Create the Controller Class.

Create a new package ("com.consistentcoder.controllers"). Then create a new class inside it ("Main").

Tutorials:
Create a New Package on Eclipse IDE
Create a New JAVA Class on Eclipse IDE

package com.consistentcoder.controllers;

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

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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;

import com.consistentcoder.models.FileUpload;
import com.consistentcoder.models.Response;

@Controller
public class Main {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(ModelMap model) {
    
        model.addAttribute("message", "Spring 4 Multiple File Upload Example.");
        return "index";
    }
    
    @RequestMapping(value="/upload", method=RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public Response handleFileUpload(@RequestParam("file") MultipartFile[] file) {

        List<String> result = new ArrayList<String>();
        FileUpload fileUpload = new FileUpload();
        for (int i = 0; i < file.length; i++) {
            result.add(fileUpload.process(file[i]));
        }

        return new Response(result);
    }
}

/src/main/java/com/consistentcoder/constrollers/Main.java

 

That's all!

Spring 4 MVC Multiple File Upload Example application has been developed.

 

Final Project Structure

 

What's Next? Test the application.

Start your server and browse this link. http://localhost:8080/spring-4-multiple-file-upload-example/

 

Upload some images.

 


References: