Spring MVC – Ví dụ Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap)

Spring MVC – Ví dụ Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap)

(Xem lại: Code ví dụ Spring MVC Upload File)

Upload File kết hợp Progress Bar

Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap). Hướng dẫn tạo một project ví dụ upload file trong Spring MVC. Kết hợp sử dụng progress bar để hiển thị phần trăm upload file.Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap). Hướng dẫn tạo một project ví dụ upload file trong Spring MVC. Kết hợp sử dụng progress bar để hiển thị phần trăm upload file.g MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC

 Spring MVC - Ví dụ Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap)

Thư viện sử dụng:

<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>stackjava.com</groupId>
  <artifactId>SpringMVCUploadFile</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>

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


  </dependencies>
</project>

Thư viện commons-fileupload được dùng để xử lý file trong form upload lên server

File Spring Config

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

  <context:component-scan base-package="stackjava.com.springmvc" />

  <mvc:annotation-driven />
  <mvc:resources mapping="/resources/**" location="/resources/bootstrap/"
    cache-period="31556926" />

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

</beans>

org.springframework.web.multipart.commons.CommonsMultipartResolver thực hiện cài đặt lại Apache Common Upload

thuộc tính maxUploadSize chỉ dẫn kích thước tối đa mà file được upload.

(lưu ý một số trường hợp bạn cần phải thay đổi kích thước file cho phép upload trên server, ví dụ server tomcat mặc định kích thước file được upload lớn nhất khoảng mấy chục Mb gì đó)

Class Model

package stackjava.com.springmvc.model;

import java.io.Serializable;

import org.springframework.web.multipart.MultipartFile;

public class MyFile implements Serializable {
  private static final long serialVersionUID = 1L;
  private MultipartFile multipartFile;
  private String description;

  //getter - setter

}

MultipartFile là đối tượng file được upload lên

Ở đây ngoài file còn có thể có một số thông tin được submit cùng nên mình thêm thuộc tính description để ví dụ

Controller

package stackjava.com.springmvc.controller;

import java.io.File;

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

import stackjava.com.springmvc.model.MyFile;

@Controller
public class BaseController {

  @RequestMapping("/")
  public String index(Model model) {
    model.addAttribute("myFile", new MyFile());

    return "index";
  }

  @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
  public String uploadFile(MyFile myFile, Model model) {
    model.addAttribute("message", "upload success");
    model.addAttribute("description", myFile.getDescription());
    
    try {
      MultipartFile multipartFile = myFile.getMultipartFile();
      String fileName = multipartFile.getOriginalFilename();
      File file = new File("D:/files", fileName);
      multipartFile.transferTo(file);
    } catch (Exception e) {
      e.printStackTrace();
      model.addAttribute("message", "upload failed");
    }
    return "result";
  }

}

File sau khi được upload sẽ được lưu vào folder D:/files

File view:

Ngoài bootstrap và jquery mình dùng thêm thư viện jquery.form.min.js để lấy trạng thái upload file.

Cái này các bạn cũng có thể tự viết js tay nhưng mình thấy thư viện này khá tiện và xử lý nhanh chóng

(Download jquery.form.min.js tại: http://malsup.github.io/min/jquery.form.min.js)

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<title>index</title>
<link href="<c:url value="/resources/css/bootstrap.min.css" />"
  rel="stylesheet">
<script src="<c:url value="/resources/js/jquery-3.2.1.min.js" />"></script>
<script src="<c:url value="/resources/js/bootstrap.min.js" />"></script>
<script src="<c:url value="/resources/js/jquery.form.min.js" />"></script>

</head>
<body>
  <form:form id="formUploadFile" method="POST" action="uploadFile" enctype="multipart/form-data" modelAttribute="myFile">
    File: <input type="file" name="multipartFile" /> <br /> <br/>
    Description: <form:input path="description"/> <br />
    <input type="submit" value="Submit" />
  </form:form>
  
  <br /> <br />
  <div class="progress" id="progressbox" style="height: 45px; width: 70%" >
    <div class="progress-bar progress-bar-striped active" id="progressbar"
      role="progressbar" aria-valuenow="80" aria-valuemin="0"
      aria-valuemax="100" style="width: 0%">
      <div id="status" style="text-align: center; width: 100%; margin-top: 10px"></div>
    </div>
  </div>
</body>

<script>
$(document).ready(function() {
  var exist = false;
  
    $('#formUploadFile').submit(function(e) {	
            e.preventDefault();
            
            $(this).ajaxSubmit({ 
                beforeSubmit: function() {
                	resetProgressBar();
                },
                uploadProgress: function (event, position, total, percentComplete){	
                    console.log(percentComplete+"");
        	        $("#progressbar").width(percentComplete + '%');
        	        if (percentComplete < 100) {
        	        	$("#status").html(percentComplete + '%');
        	        }
        	        if (percentComplete == 100) {
        	        	$("#status").html("Saving...");
        	        }
                },
                success:function (responseText, statusText, xhr){
                	$("#status").html("Completed!");
                    $("#progressbar").removeClass('progress-bar-striped active')

                },
                error: function(responseText, statusText, xhr){
                	resetProgressBar();
        			console.log(responseText);
        			console.log(statusText);
        			console.log(xhr);
                },
                //url:       url         // override for form's 'action' attribute 
                type:      'POST',        // 'get' or 'post', override for form's 'method' attribute 
                //dataType:  null        // 'xml', 'script', or 'json' (expected server response type) 
                clearForm: true,        // clear all form fields after successful submit 
                resetForm: true        // reset the form after successful submit 
            });
    });
    
    
    function resetProgressBar() {
        $("#progressbar").width(0 + '%');
        $("#progressbar").addClass('progress-bar-striped active')
        $("#status").html(0 + '%');
    }

});

</script>
</html>

Trong quá trình upload, jquery.form.js sẽ kiểm tra lượng byte đã gửi tới server để cập nhật tiến trình vào thanh progress bar

Khi status = 100% tức là đã gửi xong tới server và phải chờ server xử lý file (ghi file vào ổ đĩa, tách file.. ví dụ như khi upload video lên youtube thì sẽ tiến hành tạo các video có chất lượng khác nhau…)

Sau khi server nhận xong và xử lý xong mới coi là upload file hoàn thành.

 Controller:

package stackjava.com.springmvc.controller;

import java.io.File;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import stackjava.com.springmvc.model.MyFile;

@Controller
public class BaseController {

  @RequestMapping("/")
  public String index(Model model) {
    model.addAttribute("myFile", new MyFile());

    return "index";
  }

  @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
  public ResponseEntity<String> uploadFile(MyFile myFile) {
    try {
      MultipartFile multipartFile = myFile.getMultipartFile();
      String fileName = multipartFile.getOriginalFilename();
      File file = new File("D:/files", fileName);
      multipartFile.transferTo(file);
    } catch (Exception e) {
      e.printStackTrace();
      return new ResponseEntity<String>("failed: "+e.getMessage(),HttpStatus.BAD_REQUEST);
    }
    return new ResponseEntity<String>("success",HttpStatus.OK);
  }

}

Method uploadFile sẽ không trả về view nữa mà nó sẽ trả về response gồm status và message cho hành động upload

Demo:

Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC

Spring MVC – Phần 11: Upload File + Sử dụng Progress Bar trong Spring MVC

Spring MVC Upload File kết hợp Progress Bar (JQuery, Bootstrap) stackjava.com

Okay, Done!

Download code ví dụ trên tại đây.

 

References:

https://commons.apache.org/proper/commons-fileupload/

stackjava.com