Spring 4 MVC - JQuery Ajax file upload example with progress bar



Spring 4 MVC - JQuery Ajax file upload example with progress bar

In this section, I will show you how to use the JQuery’s Ajax function to upload a file with progress bar in Spring MVC application.

We will use the Bootstrap’s progress bar component and XmlHttpRequest’s onprogress event handler for displaying the file upload progress.

Tools and technologies used for this example are –

  • Spring MVC 4.3.7.RELEASE
  • Bootstrap 3.3.7
  • JQuery 3.2.1
  • Eclipse Neon.3
  • Maven 3.3.9
  • JavaSE 1.8
  • Apache Tomcat  7.0.47 (Embedded)

Let us proceed to write a simple Spring MVC application to upload a file using the JQuery’s Ajax function.

 

Project structure

Review the following web project structure build using Maven.

Spring 4 MVC – JQuery Ajax file upload example  | BORAJI.COM

Related - How to create a web project using maven build tool in eclipse IDE.

 

Jar dependencies

Open pom.xml file of your maven project and add the following dependencies in it.

<dependencies>
  <!-- Spring MVC Dependency -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.7.RELEASE</version>
  </dependency>

  <!-- Commons Fileupload -->
  <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
  </dependency>
  
  <!-- JSTL Dependency -->
  <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
  </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
  </dependency>

  <!-- Servlet Dependency -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>

  <!-- JSP Dependency -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.1</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

 

Controller class

Create a controller class to handle the file upload request as follows.

FileUploadController.java

package com.boraji.tutorial.spring.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author imssbora
 */
@Controller
public class FileUploadController {

   @GetMapping("/")
   public String fileUploadForm(Model model) {
      return "fileUploadForm";
   }

   // Handling file upload request
   @PostMapping("/fileUpload")
   public ResponseEntity<Object> fileUpload(@RequestParam("file") MultipartFile file)
         throws IOException {

      // Save file on system
      if (!file.getOriginalFilename().isEmpty()) {
         BufferedOutputStream outputStream = new BufferedOutputStream(
               new FileOutputStream(
                     new File("D:/Upload", file.getOriginalFilename())));
         outputStream.write(file.getBytes());
         outputStream.flush();
         outputStream.close();
      }else{
         return new ResponseEntity<>("Invalid file.",HttpStatus.BAD_REQUEST);
      }
      
      return new ResponseEntity<>("File Uploaded Successfully.",HttpStatus.OK);
   }
}

ResponseEntity represent the HTTP response entity that contains body, header and status code. It can be used in RestTemplate and @Controller method.

 

JSP View

Create a fileUploadForm.jsp file under src\main\webapp\WEB-INF\views folder to send a file to controller’s handler method via JQuery.ajax() function.

fileUploadForm.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
<!-- CSS for Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- JQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<script type="text/javascript">
$(function() {
  $('button[type=submit]').click(function(e) {
    e.preventDefault();
    //Disable submit button
    $(this).prop('disabled',true);
    
    var form = document.forms[0];
    var formData = new FormData(form);
    	
    // Ajax call for file uploaling
    var ajaxReq = $.ajax({
      url : 'fileUpload',
      type : 'POST',
      data : formData,
      cache : false,
      contentType : false,
      processData : false,
      xhr: function(){
        //Get XmlHttpRequest object
         var xhr = $.ajaxSettings.xhr() ;
        
        //Set onprogress event handler 
         xhr.upload.onprogress = function(event){
          	var perc = Math.round((event.loaded / event.total) * 100);
          	$('#progressBar').text(perc + '%');
          	$('#progressBar').css('width',perc + '%');
         };
         return xhr ;
    	},
    	beforeSend: function( xhr ) {
    		//Reset alert message and progress bar
    		$('#alertMsg').text('');
    		$('#progressBar').text('');
    		$('#progressBar').css('width','0%');
              }
    });
  
    // Called on success of file upload
    ajaxReq.done(function(msg) {
      $('#alertMsg').text(msg);
      $('input[type=file]').val('');
      $('button[type=submit]').prop('disabled',false);
    });
    
    // Called on failure of file upload
    ajaxReq.fail(function(jqXHR) {
      $('#alertMsg').text(jqXHR.responseText+'('+jqXHR.status+
      		' - '+jqXHR.statusText+')');
      $('button[type=submit]').prop('disabled',false);
    });
  });
});
</script>

</head>
<body>
  <div class="container">
    <h2>Spring MVC - File Upload Example With Progress Bar</h2>
    <hr>
    <!-- File Upload From -->
    <form action="fileUpload" method="post" enctype="multipart/form-data">
      <div class="form-group">
        <label>Select File</label> 
        <input class="form-control" type="file" name="file">
      </div>
      <div class="form-group">
        <button class="btn btn-primary" type="submit">Upload</button>
      </div>
    </form>
    <br />

    <!-- Bootstrap Progress bar -->
    <div class="progress">
      <div id="progressBar" class="progress-bar progress-bar-success" role="progressbar"
        aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">0%</div>
    </div>

    <!-- Alert -->
    <div id="alertMsg" style="color: red;font-size: 18px;"></div>
  </div>
</body>
</html>

 

Spring configuration

Create a web @Configuration class annotated with @EnableWebMvc and @ComponentScan as follows. 

To support multipart handling in Spring application, declare CommonsMultipartResolver bean method in configuration class.

WebConfig.java

package com.boraji.tutorial.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * @author imssbora
 */

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.boraji.tutorial.spring.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setViewClass(JstlView.class);
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }

   @Bean
   public MultipartResolver multipartResolver() {
      CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
      multipartResolver.setMaxUploadSize(10485760); // 10MB
      multipartResolver.setMaxUploadSizePerFile(1048576); // 1MB
      return multipartResolver;
   }

}

 

Servlet container initialization

Create a container initializer class by extending the AbstractAnnotationConfigDispatcherServletInitializer class as follows.

MyWebAppInitializer.java

package com.boraji.tutorial.spring.config;

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

/**
 * @author imssbora
 */
public class MyWebAppInitializer
      extends AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

The AbstractAnnotationConfigDispatcherServletInitializer class, implements the WebApplicationInitializer, is implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically.

 

Build + Deploy + Run application

Use the following maven commands to build, deploy and run embedded Tomcat server.

mvn clean install  (This command triggers war packaging)

mvn tomcat7:run (This command run embedded tomcat and deploy war file automatically)

You can refer this link to learn how to run the above commands in Eclipse IDE.


Type the following URLs in browser's address bar to open the file upload from.

http://localhost:8080/

Spring 4 MVC – JQuery Ajax file upload example  | BORAJI.COM

Select a file and click on Upload button. On successful upload of a file, you will see the below screen. 

Spring 4 MVC – JQuery Ajax file upload example  | BORAJI.COM