webuploader与SpingMVC

前端代码

<%@ page language="java" pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>使用webuploader上传</title>
<!-- 引入资源 -->
<link rel="stylesheet" type="text/css" href="../baidu/webuploader.css">
<link rel="stylesheet" type="text/css" href="../baidu/bootstrap.min.css">
<script type="text/javascript" src="../baidu/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="../baidu/webuploader.js"></script>
<style type="text/css">
	#dndArea{
		width: 300px;
		height: 150px;
		border-color: green;
		border-style: dotted;
	}
</style>
</head>
<body>
	<!-- 准备dom结构 -->
	<div id="uploader">
		<!-- 文件选择 -->
		<div id="filePicker">选择文件</div>
		<!-- 可拖拽区域 -->
		<div id="dndArea"></div>
		<div>单个文件不允许超过200M,过大将无法添加</div>
		<!-- 文件列表 -->
		<div id="fileList"></div>
		<button id="btn" class="btn btn-default">开始上传</button>
	</div>
	<!-- js部分 -->
	<script type="text/javascript">
		// 监听分块上传的时间点,断点续传
		var fileMd5;
		var state = 'pending';//初始按钮状态
		var $btn=$("#btn");
		//注册组件
		WebUploader.Uploader.register({
			"before-send-file":"beforeSendFile",
			"before-send":"beforeSend",
			"after-send-file":"afterSendFile"
			},{
				beforeSendFile:function(file) {
					// 创建一个deffered,用于通知是否完成操作
					var deferred = WebUploader.Deferred();
					// 计算文件MD5值,用于断点续传
					(new WebUploader.Uploader()).md5File(file, 0, 5*1024*1024)
						.progress(function(percentage){
							$("#"+file.id).find("span.state").text("正在获取文件信息...");
						})
						.then(function(val) {
							fileMd5 = val;
							$("#" + file.id).find("span.state").text("成功获取文件信息");
							// 放行
							deferred.resolve();
						});
					// 通知完成操作
					return deferred.promise();
				},
				beforeSend:function(block) {
					var deferred = WebUploader.Deferred();
					// 支持断点续传,发送到后台,判断是否已经上传过
					$.ajax(
						{
							type:"POST",
							url:"/checkChunk",
							data:{
								// 文件MD5值								
								fileMd5:fileMd5,
								// 当前分块下标
								chunk:block.chunk,
								// 当前分块大小
								chunkSize:block.end-block.start
							},
							dataType:"json",
							success:function(response) {
								if(response.ifExist) {
									// 分块存在,跳过该分块
									deferred.reject();
								} else {
									// 分块不存在或不完整,重新上传此分块
									deferred.resolve();
								}
							}
						}
					);
					// 发送文件md5字符串到后台
					this.owner.options.formData.fileMd5 = fileMd5;
					return deferred.promise();
				},
				afterSendFile:function() {
					// 合并分块
					$.ajax(
						{
							type:"POST",
							url:"/mergeChunks",
							data:{ fileMd5:fileMd5},
							success:function(response){
								alert("上传成功")
							}
						}
					);
				}
			}
		);
	
		// 初始化
		var uploader = WebUploader.create(
			{
				swf:"../baidu/Uploader.swf",
				server:"/FileUpload",
				pick:"#filePicker",
				auto:false,//不自动上传
				dnd:"#dndArea",//指定拖拽的容器
				disableGlobalDnd:true,//是否禁掉整个页面的拖拽功能
				paste:"#uploader",
				fileSingleSizeLimit:200*1024*1024,//单个文件最大值200M
				chunked:true,//文件分块上传
				chunkSize:5*1024*1024,// 每块文件大小为5M
				threads:3,// 开启几个并非线程(默认3个)
				prepareNextFile:true// 在上传当前文件时,准备好下一个文件,提高上传速度
			}		
		);
		
		// 生成缩略图
		uploader.on("fileQueued", function(file) {
				// 把文件信息追加到fileList的div中
				$("#fileList").append("<div id='" + file.id + "'><img/><span>" + file.name + "</span><div><span class='state'></span></div><div><span class='percentage'></span></div></div>");
				
				// 制作缩略图
				// error:上传文件不是图片,则有error
				// src:代表生成缩略图的地址
				uploader.makeThumb(file, function(error, src) {
					if (error) {
						$("#" + file.id).find("img").replaceWith("<span style='color: #778899'>无法预览&nbsp;</span>");
					} else {
						$("#" + file.id).find("img").attr("src", src);
					}
				});
			}
		);
		
		 // 文件上传时,进度显示。
	    uploader.on('uploadProgress', function (file, percentage) {
	        //进度百分比显示
	    	$("#" + file.id).find("span.percentage").text(Math.round(percentage * 100) + "%");
	        var $li = $('#' + file.id),
	        //进度条显示
	        $percent = $li.find('.progress .progress-bar');
	        // 避免重复创建
	        if (!$percent.length) {
	            $percent = $('<div class="progress progress-striped active">' +
	                    '<div class="progress-bar" role="progressbar" style="width: 0%">' +
	                    '</div>' +
	                    '</div>').appendTo($li).find('.progress-bar');
	      	 }
	        $li.find('p.state').text('上传中');
	        $percent.css('width', percentage * 100 + '%');
	    });
		
		//上传成功
	    uploader.on( "uploadSuccess", function( file ) {
	        $( "#"+file.id ).find("p.state").text("已上传");
	        $('#' + file.id).find('.progress').fadeOut();
	    });

	  //上传失败
	    uploader.on( "uploadError", function( file ) {
	        $( "#"+file.id ).find("p.state").text("上传出错");
	        uploader.cancelFile(file);
	        uploader.removeFile(file,true);
	    });

       //暂停与继续上传
		uploader.on('all', function(type) {
			if (type === 'startUpload') {
				state = 'uploading';
			} else if (type === 'stopUpload') {
				state = 'paused';
			} else if (type === 'uploadFinished') {
				state = 'done';
			}

			if (state === 'uploading') {
				$btn.text('暂停上传');
			} else {
				$btn.text('开始上传');
			}
		});
		
		$btn.on('click', function(){  
	        if (state === 'uploading'){  
	            uploader.stop(true);  
	        } else {  
	        	uploader.upload();
	        }
		});
	</script>
</body>
</html>

后端代码

package com.cn.controller;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UploadController {


	private String serverPath = "E:"+File.separator+"test"+File.separator;
	
	// 合并分块文件
	@RequestMapping("/mergeChunks")
	public void mergeChunks(HttpServletRequest request,HttpSession session,
			HttpServletResponse response) throws IOException {
		// 获得需要合并的目录
		String fileMd5 = request.getParameter("fileMd5");
		// 读取目录所有文件
		File f = new File(serverPath + fileMd5);
		File[] fileArray = f.listFiles(new FileFilter() {
			// 排除目录,只要文件
			@Override
			public boolean accept(File pathname) {
				if (pathname.isDirectory()) {
					return false;
				}
				return true;
			}
		});
		// 转成集合,便于排序
		List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
		// 从小到大排序
		Collections.sort(fileList, new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
					return -1;
				}
				return 1;
			}

		});
		// 新建保存文件
		String type = (String) session.getAttribute("type");
		File outputFile = new File(serverPath + UUID.randomUUID().toString() + "."+type);
		// 创建文件
		outputFile.createNewFile();
		// 输出流
		FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
		FileChannel outChannel = fileOutputStream.getChannel();
		// 合并
		FileChannel inChannel;
		for (File file : fileList) {
			inChannel = new FileInputStream(file).getChannel();
			inChannel.transferTo(0, inChannel.size(), outChannel);
			inChannel.close();
			// 删除分片
			file.delete();
		}
		// 关闭流
		fileOutputStream.close();
		outChannel.close();
		// 清除文件夹
		File tempFile = new File(serverPath + fileMd5);
		if (tempFile.isDirectory() && tempFile.exists()) {
			tempFile.delete();
		}
	}

	// 校验文件是否已经上传, 并返回检验结果给前端
	@RequestMapping("/checkChunk")
	public void checkChunk(HttpServletRequest request, HttpSession session,
			HttpServletResponse response) throws IOException {
		// 文件MD5值
		String fileMd5 = request.getParameter("fileMd5");
		// 当前分块下标
		String chunk = request.getParameter("chunk");
		// 当前分块大小
		String chunkSize = request.getParameter("chunkSize");
		// 找到分块文件
		File checkFile = new File(serverPath + fileMd5 + File.separator + chunk);
		// 检查文件是否存在,且大小一致,返回判断结果
		response.setContentType("text/html;charset=utf-8");
		if (checkFile.exists() && checkFile.length() == Integer.parseInt((chunkSize))) {
			response.getWriter().write("{\"ifExist\":1}");
		} else {
			response.getWriter().write("{\"ifExist\":0}");
		}
	}
	
	
	// 保存分块后的小文件
	@RequestMapping("/FileUpload")
	public void FileUpload(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		// 1.创建DiskFileItemFactory对象
		DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
		// 2. 创建 ServletFileUpload对象
		ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
		// 3. 设置文件名称编码
		servletFileUpload.setHeaderEncoding("utf-8");
		// 4. 开始解析文件
		// 文件md5获取的字符串
		String fileMd5 = null;
		// 文件的索引
		String chunk = null;
		try {
			List<FileItem> items = servletFileUpload.parseRequest(request);
			for (FileItem fileItem : items) {
				if (fileItem.isFormField()) { // 普通数据
					String fieldName = fileItem.getFieldName();
					if ("info".equals(fieldName)) {
						String info = fileItem.getString("utf-8");
					}
					if ("fileMd5".equals(fieldName)) {
						fileMd5 = fileItem.getString("utf-8");
					}
					if ("chunk".equals(fieldName)) {
						chunk = fileItem.getString("utf-8");
					}
				} else { // 文件数据
					//确定文件类型
					session.setAttribute("type",  fileItem.getName().split("\\.")[1]);
					// 如果文件夹没有,则创建
					File file = new File(serverPath + fileMd5);
					if (!file.exists()) {
						file.mkdirs();
					}
					// 保存文件
					File chunkFile = new File(serverPath + fileMd5 + File.separator + chunk);
					FileUtils.copyInputStreamToFile(fileItem.getInputStream(), chunkFile);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

注意

servletFileUpload.parseRequest(request) 返回值为空,请检查SpingMVC的配置文件中,是否配置了multipartResolver。若有,请删除此配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值