前段WebUploader;JavaEE大文件分片上传接收
2016-07-31 11:59
471 查看
Web大文件分片上传
Web环境中大文件上传不能再用form表单一次上传了,这样效率太低;
我在不断尝试SpringMVC环境下分片接受文件,最终失败;原因目测是 SpringMVC、Struts框架是不支持HTML5方式上传的(这类框架只能支持Form表单方式的文件上传,或者FLash)
那我们可以使用Servlet和SpringMVC结合集成方式实现大文件分片上传;
一、来看看我们的web.xml的配置
![](https://img-blog.csdn.net/20160731115556293)
很明显两个servlet,上面一个配置的是SpringMVC的入口,下面servlet是视频上传;
他们俩的url-pattern 不能冲突;
二、先来看看WebUploader 的前端代码
![](https://img-blog.csdn.net/20160731115622803)
以下是代码:
三、servlet分片获取
分片就是前段将文件分成多个,每片都是一个post请求,有多少片就请求多少次servlet;
我们以获取的guid为文件名 建立临时文件夹,以chunk(片序号)为文件名来存储文件;
![](https://img-blog.csdn.net/20160731115717590)
以下为代码:
四、前端WebUploader上传完毕触发uploadSuccess事件
请求servlet去合并之前的guid文件夹下的分片文件,post请求中的分片数量可以用来校验,获取的分片是否正确,也可以前端传递md5,后台校验;
五、后台获取的log
![](https://img-blog.csdn.net/20160731115830622)
![](https://img-blog.csdn.net/20160731115850807)
图:上传的GUID命名的文件夹
![](https://img-blog.csdn.net/20160731115914622)
图:文件夹下的分片文件
每个分割线包住的地方是一个servlet请求,最后在success 请求的servlet是进行文件校验并合并文件即可;代码见下:
六、java文件合并
代码见下:
文件夹以guid命名,数据库储存guid的名字,后期数据移动,只需要更改前端显示的路径;
在这里up遇到一个问题,上传报错:IOException:磁盘空间不足;然而我上传的磁盘还有20G;原因是系统盘空间不足;up重装系统就好了;
注:
1、进度条的显示就很容易了
引入bootstrap的进度条
2.添加uploadProgress事件监听
percentage:当前上传的进度,小数,数值为1是上传完毕;
效果如下:
PS:UI简陋还请见谅!
源代码下载:http://pan.baidu.com/s/1nv93iqP 密码:78an
QQ:346640094 Email:lcx1995@foxmail.com;
Web环境中大文件上传不能再用form表单一次上传了,这样效率太低;
我在不断尝试SpringMVC环境下分片接受文件,最终失败;原因目测是 SpringMVC、Struts框架是不支持HTML5方式上传的(这类框架只能支持Form表单方式的文件上传,或者FLash)
那我们可以使用Servlet和SpringMVC结合集成方式实现大文件分片上传;
一、来看看我们的web.xml的配置
很明显两个servlet,上面一个配置的是SpringMVC的入口,下面servlet是视频上传;
他们俩的url-pattern 不能冲突;
二、先来看看WebUploader 的前端代码
以下是代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/"> <script type="text/javascript" src="webuploader/jquery-1.7.2.js"></script> <script type="text/javascript" src="webuploader/webuploader.min.js"></script> <link href="webuploader/webuploader.css" type="css/text" /> </head> <body> <h2>Hello World!</h2> <div id="thelist" class="uploader-list"></div> <div style="margin: 20px 20px 20px 0;"> <div id="picker" class="form-control-focus">选择文件</div> </div> <button id="btnSync" type="button" class="btn btn-warning">开始同步</button> <script> var uploader = WebUploader.create({ // swf文件路径 swf : 'webuploader/Uploader.swf', // 文件接收服务端。 server : 'UploadVideoServlet', // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick : '#picker', threads:2, chunked: true, //分片处理 chunkSize: 5 * 1024 * 1024, //每片5M threads:1,//上传并发数。允许同时最大上传进程数。 // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize : false }); // 当有文件被添加进队列的时候 uploader.on('fileQueued', function(file) { //alert(123); $("#thelist").append( '<div id="' + file.id + '" class="item">' + '<h4 class="info">' + file.name + '</h4>' + '<p class="state">等待上传...</p>' + '</div>'); }); uploader.on('uploadSuccess', function(file) { alert(uploader.options.formData.guid); alert(Math.ceil(file.size/(5*1024*1024))); alert(file.name); $('#' + file.id).find('p.state').text('已上传'); $.post("UploadSuccessServlet", { "guid": uploader.options.formData.guid,chunks:Math.ceil(file.size/(5*1024*1024)),fileName:file.name}, function(data){ }, "json"); }); uploader.on('uploadError', function(file) { $('#' + file.id).find('p.state').text('上传出错'); }); uploader.on('uploadComplete', function(file) { $('#' + file.id).find('.progress').fadeOut(); }); $("#btnSync").on('click', function() { if ($(this).hasClass('disabled')) { return false; } uploader.options.formData.guid = Math.random(); uploader.upload(); }); </script> </body> </html>
三、servlet分片获取
分片就是前段将文件分成多个,每片都是一个post请求,有多少片就请求多少次servlet;
我们以获取的guid为文件名 建立临时文件夹,以chunk(片序号)为文件名来存储文件;
以下为代码:
package com.airodlcx; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; /** * Servlet implementation class UploadVideo */ public class UploadVideoServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public UploadVideoServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getSession().getServletContext().getRealPath("/upload"); System.out.println(path); DiskFileItemFactory factory = new DiskFileItemFactory(); // 2、创建一个文件上传解析器 ServletFileUpload upload = new ServletFileUpload(factory); // 解决上传文件名的中文乱码 upload.setHeaderEncoding("UTF-8"); // 3、判断提交上来的数据是否是上传表单的数据 if (!ServletFileUpload.isMultipartContent(request)) { return; } // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项 List<FileItem> list = null; try { list = upload.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); } HashMap<String, String> map = new HashMap<String, String>(); System.out.println("-------------------------------------------------------------"); for (FileItem item : list) { if (item.isFormField()) { /** * 表单数据 */ String name = item.getFieldName(); // 解决普通输入项的数据的中文乱码问题 String value = item.getString("UTF-8"); // value = new String(value.getBytes("iso8859-1"),"UTF-8"); System.out.println(name + "=" + value); map.put(name, value);// 放入map集合 } else { /** * 文件上传 */ File fileParent = new File(path + "/" + map.get("guid"));//以guid创建临时文件夹 System.out.println(fileParent.getPath()); if (!fileParent.exists()) { fileParent.mkdir(); } String filename = item.getName(); if (filename == null || filename.trim().equals("")) { continue; } // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: // c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分 filename = filename.substring(filename.lastIndexOf("\\") + 1); //创建文件 File file; if (map.get("chunks") != null) { file = new File(fileParent, map.get("chunk")); } else { file = new File(fileParent, "0"); } //copy FileUtils.copyInputStreamToFile(item.getInputStream(), file); } } } }
四、前端WebUploader上传完毕触发uploadSuccess事件
uploader.on('uploadSuccess', function(file) { alert(uploader.options.formData.guid); alert(Math.ceil(file.size/(5*1024*1024))); alert(file.name); $('#' + file.id).find('p.state').text('已上传'); $.post("UploadSuccessServlet", { "guid": uploader.options.formData.guid,chunks:Math.ceil(file.size/(5*1024*1024)),fileName:file.name}, function(data){ }, "json"); });
请求servlet去合并之前的guid文件夹下的分片文件,post请求中的分片数量可以用来校验,获取的分片是否正确,也可以前端传递md5,后台校验;
五、后台获取的log
图:上传的GUID命名的文件夹
图:文件夹下的分片文件
每个分割线包住的地方是一个servlet请求,最后在success 请求的servlet是进行文件校验并合并文件即可;代码见下:
六、java文件合并
代码见下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getSession().getServletContext().getRealPath("/upload"); String guid = request.getParameter("guid"); int chunks = Integer.parseInt(request.getParameter("chunks")); String fileName = request.getParameter("fileName"); System.out.println("start...!guid="+guid+";chunks="+chunks+";fileName="+fileName); /** * 进行文件合并 */ File file = new File(path+"/"+guid); /** * 判断分片数量是否正确 */ if(file.list().length != chunks){ return; } new File("F://upload"+"/"+guid).mkdir(); /** * 进行文件合并 */ File newFile = new File("F://upload"+"/"+guid+"/"+fileName); FileOutputStream outputStream = new FileOutputStream(newFile, true);//文件追加写入 byte[] byt = new byte[10*1024*1024]; int len; FileInputStream temp = null;//分片文件 for(int i = 0 ; i<chunks ; i++){ temp = new FileInputStream(new File(path+"/"+guid+"/"+i)); while((len = temp.read(byt))!=-1){ System.out.println(len); outputStream.write(byt, 0, len); } } /** * 当所有追加写入都写完 才可以关闭流 */ outputStream.close(); temp.close(); System.out.println("success!guid="+guid+";chunks="+chunks+";fileName="+fileName); }
文件夹以guid命名,数据库储存guid的名字,后期数据移动,只需要更改前端显示的路径;
在这里up遇到一个问题,上传报错:IOException:磁盘空间不足;然而我上传的磁盘还有20G;原因是系统盘空间不足;up重装系统就好了;
注:
1、进度条的显示就很容易了
引入bootstrap的进度条
<div class="progress"> <div id="progress" class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> <span class="sr-only">60% Complete</span> </div> </div>
2.添加uploadProgress事件监听
uploader.on('uploadProgress', function(file,percentage) { $("#progress").css("width",parseInt(percentage*100)+"%"); });
percentage:当前上传的进度,小数,数值为1是上传完毕;
效果如下:
PS:UI简陋还请见谅!
源代码下载:http://pan.baidu.com/s/1nv93iqP 密码:78an
QQ:346640094 Email:lcx1995@foxmail.com;
相关文章推荐
- webuploader服务器端接收文件的脚本分析,server端怎么接收上传的文件和图片-百度webuploader教程5
- 百度Webuploader 大文件分片上传(.net接收)
- WebUploader 上传的文件与表单接收方法
- 百度Webuploader 大文件分片上传(.net接收)
- webuploader+python3(BaseHTTPRequestHandler)实现图片文件的上传与接收存储
- webuploader文件接收服务端(文件上传)
- Android上传文件到Web服务器,PHP接收文件(二)
- 百度 flash html5自切换 多文件异步上传控件webuploader基本用法
- Android上传文件到Web服务器,PHP接收文件
- 利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
- Web文件批量上传控件-Xproer.HttpUploader发布
- 用百度webuploader分片上传大文件
- [置顶] Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(一)
- Web文件批量上传控件-Xproer.HttpUploader发布
- webuploader上传文件插件
- Web大文件上传断点续传控件4升级日志-Xproer.HttpUploader4
- Web大文件上传断点续传控件5发布-HttpUploader5
- [置顶] Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(2)