spring boot带进度条文件上传简单实例

本文使用ajax方法来实现文件上传带进度条显示。进度条样式使用了Bootstrap的progress bar组件。进度条的计算使用了XmlHttpRequest的onprogress事件控制器。

使用到的技术:

  • Spring Boot
  • Thymelead(前台模板引擎)
  • Bootstrap 4.4.1
  • JQuery 3.4.1
  • Maven,Java SE1.8,Apache Tomcat等

项目结构(红框内为关联文件,yml等基础配置也是需要的)
在这里插入图片描述

YML启动文件,注意设置文件上传的大小限制,默认的是10MB。

server:
  #端口号设为8082
  port: 8082
spring:
  mvc:
    #静态文件路径
    static-path-pattern: /static/**
  thymeleaf:
    enabled: true
    #编码格式
    encoding: UTF-8
    #模板前缀
    prefix: classpath:/templates/
    #模板后缀
    suffix: .html
  servlet:
    multipart:
      #上传文件的文件大小限制
      max-file-size: 200MB 
      max-request-size: 200MB

前台HTML部分

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="/static/css/style.css">
<!-- 引入jquery css&js -->
<!-- CDN为国外源,如不可访问请自行切换 -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<!-- 引入bootstrap css&js -->
<!-- CDN为国外源,如不可访问请自行切换 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-10 mx-auto">
				<form class="mt-5" method="post" enctype="multipart/form-data">
					<div class="input-group">
					    <div class="custom-file">
					        <input type="file" class="custom-file-input" id="customFile" name="file">
					        <label class="custom-file-label" for="customFile" data-browse="选择文件">点击选择...</label>
					    </div>
					    <div class="input-group-append">
					        <button type="button" class="btn btn-outline-secondary reset">重选</button>
					    </div>
					</div>
					<div class="row mt-3">
						<div class="col-12">
							<div class="text-center">
								<button type="submit" id="uploadFileBtn" class="btn btn-outline-secondary">提交</button>
							</div>
						</div>
					</div>
				</form>
				<!-- Bootstrap Progress bar -->
			    <div class="progress mt-3">
			      <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>
				<!-- Bootstrap Alert -->
    			<div id="alertDiv" class="mt-3 alert alert-warning alert-dismissible fade" role="alert">
    			  <font id="alertMsg"></font>
				  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
				    <span aria-hidden="true">&times;</span>
				  </button>
				</div>
    			
			</div>
		</div>
	</div>
	
	<!-- 引入upload.js -->
	<script src="/static/js/upload.js"></script>
</body>
</html>

实际显示效果
在这里插入图片描述

Javascript部分如下:

// 当input标签文件被置换
$('.custom-file-input').on('change',function(){
    $(this).next('.custom-file-label').html($(this)[0].files[0].name);
    // 恢复提交按钮
    $('button[type=submit]').prop('disabled',false);
});
// 重选文件,重选按钮被点击后执行
$('.reset').click(function(){
    $(this).parent().prev().children('.custom-file-label').html('点击选择...');
    $('.custom-file-input').val('');
    // 恢复提交按钮
    $('button[type=submit]').prop('disabled',false);
});
// 提交按钮被点击后执行
$("#uploadFileBtn").click(function(e){
	
	e.preventDefault();
    // 置灰按钮无效,前台防止双重提交
    $(this).prop('disabled',true);
    
    // 获取文件
    var file = $('#customFile')[0].files[0];
    var formData = new FormData();
    formData.append("file",file);
    
	 $.ajax({
	      url : '/fileUpload',
	      type : 'POST',
	      data : formData,
	      cache : false,
	      contentType : false,
	      processData : false,
	      xhr: function(){
	        //Get XmlHttpRequest object
	         var xhr = $.ajaxSettings.xhr() ;
	        
	        // 设置onprogress事件控制器 
	         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 ) {
	    		// 提交前重置提示消息为空,并重置进度条
	    		$('#alertMsg').text('');
	    		$('#progressBar').text('');
	    		$('#progressBar').css('width','0%');
	              }
	  })
	  .done(function(msg){
		  // 添加提示框显示类
		  $('#alertDiv').addClass("show");
		  // 设置返回消息
		  $('#alertMsg').text(msg);
		  // 清空文件
	      $('input[type=file]').val('');
	      // 恢复提交按钮
	      $('button[type=submit]').prop('disabled',false);
	  })
	  .fail(function(jqXHR){
		  // 添加提示框显示类
		  $('#alertDiv').addClass("show");
		  // 设置返回消息
		  $('#alertMsg').text("发生错误");
	  });
	 return false;
});

Controller中有两个方法,一个为初始化当前上传画面的方法。另一个为接受上传文件并保存到指定目录的方法。

初始化的方法对应的url为http://localhost:8082/upload
接受上传文件的方法对应的url为http://localhost:8082/fileUpload

Controller的接口如下:

package com.example.demo.controller;

import java.io.IOException;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public interface ExampleController {

	/*
	 * 概要:初期化上传画面
	 * 输入:              -                -
	 * 输出:   ModelAndView    modelAndView 
	 * @throws
	 */
	@GetMapping(value="/upload")
	ModelAndView upload();
	
	/*
	 * 概要:接受上传文件
	 * 输入:     MultipartFile        file
	 * 输出:   ResponseEntity    responseEntity 
	 * @throws IOException
	 */
	@PostMapping(value="/fileUpload")
	ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) throws IOException;
	
}

Controller实现方法如下:

package com.example.demo.controllerImpl;

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.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.example.demo.constant.SystemConstants;
import com.example.demo.controller.ExampleController;

@Component
public class ExampleControllerImpl implements ExampleController{

	@Override
	public ModelAndView upload() {
		// TODO Auto-generated method stub
		ModelAndView modelAndView = new ModelAndView();
		
		// 设置视图名称,这里设定了固定变量,变量实际值为"upload-file",由于后缀.html已经在yml文件设定了
		// 因此括号内可直接替换为
		// modelAndView.setViewName("upload-file");
		modelAndView.setViewName(SystemConstants.PAGE_UPLOAD);
		return modelAndView;
	}

	@Override
	public ResponseEntity<?> uploadFile(MultipartFile file) throws IOException {
		// TODO Auto-generated method stub

	      // 如果文件不为空
	      if (!file.getOriginalFilename().isEmpty()) {
	         BufferedOutputStream outputStream = new BufferedOutputStream(
	               new FileOutputStream(
	            		   // 注意改为自己电脑的路径
	                     new File("C:/Users/zhewen.li/wktechno-test", file.getOriginalFilename())));
	         outputStream.write(file.getBytes());
	         outputStream.flush();
	         outputStream.close();
	      }else{
	         return new ResponseEntity<>("空文件或不合法文件。",HttpStatus.BAD_REQUEST);
	      }
		
		return new ResponseEntity("文件上传成功",HttpStatus.OK);
	}
}

存放固定常量的java文件,此存放模板名称的,非必须

package com.example.demo.constant;

public class SystemConstants {

	public final static String PAGE_UPLOAD = "upload-file";
	
}

实际执行效果:

在这里插入图片描述

选择视频文件:Autumn_leaves_12_time-lapse.mp4,并点击提交。

在这里插入图片描述

确认文件被成功上传
在这里插入图片描述

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值