WebUploader,Java大文件分片上传

更新时间:2023-12-22 23:19:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Web大文件分片上传

Web环境中大文件上传不能再用form表单一次上传了,这样效率太低;

我在不断尝试SpringMVC环境下分片接受文件,最终失败;原因目测是 SpringMVC、Struts

框架是不支持HTML5方式上传的(这类框架只能支持Form表单方式的文件上传,或者FLash)

那我们可以使用Servlet和SpringMVC结合集成方式实现大文件分片上传;

一、来看看我们的web.xml的配置

很明显两个servlet,上面一个配置的是SpringMVC的入口,下面servlet是视频上传; 他们俩的url-pattern不能冲突;

二、先来看看WebUploader的前端代码

以下是代码:

<%@pagelanguage=\contentType=\

pageEncoding=\%>

Transitional//EN\\>

href=\${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/\>

Hello World!

选择文件

开始同步

// swf文件路径

swf : 'webuploader/Uploader.swf', // 文件接收服务端。

server : 'UploadVideoServlet', // 选择文件的按钮。可选。

// 内部根据当前运行是创建,可能是input元素,也可能是flash. pick : '#picker', threads:2,

chunked: true, //分片处理

$(\).on('click', function() {

if ($(this).hasClass('disabled')) { }

uploader.options.formData.guid = Math.random(); uploader.upload();

returnfalse;

uploader.on('uploadComplete', function(file) {

$('#' + file.id).find('.progress').fadeOut(); });

uploader.on('uploadError', function(file) {

$('#' + file.id).find('p.state').text('上传出错');

function(data){

}, \);

});

});

三、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 {

/**

* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */

protected void doGet(HttpServletRequest request, HttpServletResponse response) }

throws ServletException, IOException {

/**

* @see HttpServlet#HttpServlet() */

public UploadVideoServlet() { }

super();

// TODO Auto-generated constructor stub private static final long serialVersionUID = 1L;

// TODO Auto-generated method stub

response.getWriter().append(\

/**

* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String path = request.getSession().getServletContext().getRealPath(\System.out.println(path);

DiskFileItemFactory factory = new DiskFileItemFactory(); // 2、创建一个文件上传解析器

ServletFileUpload upload = new ServletFileUpload(factory); // 解决上传文件名的中文乱码 upload.setHeaderEncoding(\

// 3、判断提交上来的数据是否是上传表单的数据 if (!ServletFileUpload.isMultipartContent(request)) { }

// 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个

return;

List集合,每一个FileItem对应一个Form表单的输入项

List list = null; try {

list = upload.parseRequest(request);

} catch (FileUploadException e) { }

e.printStackTrace();

HashMap map = new HashMap();

System.out.println(\for (FileItem item : list) {

if (item.isFormField()) {

/**

* 表单数据 */

String name = item.getFieldName(); // 解决普通输入项的数据的中文乱码问题 String value = item.getString(\

// value = new String(value.getBytes(\System.out.println(name + \map.put(name, value);// 放入map集合

} else {

/**

* 文件上传

*/

File fileParent = new File(path + \以guid创建临时

文件夹

System.out.println(fileParent.getPath()); if (!fileParent.exists()) { }

String filename = item.getName();

if (filename == null || filename.trim().equals(\ }

// 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来

continue; fileParent.mkdir();

的文件名是带有路径的,如:

//创建文件 File file;

// c:\\a\\b\\1.txt,而有些只是单纯的文件名,如:1.txt

// 处理获取到的上传文件的文件名的路径部分,只保留文件名部分 filename = filename.substring(filename.lastIndexOf(\

}

}

}

}

if (map.get(\

file = new File(fileParent, map.get(\

} else { } //copy

FileUtils.copyInputStreamToFile(item.getInputStream(), file);

file = new File(fileParent, \

四、前端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(\, { \:

uploader.options.formData.guid,chunks:Math.ceil(file.size/(5*1024*1024)),fileName:file.name},

请求servlet去合并之前的guid文件夹下的分片文件,post请求中的分片数量可以用来校

function(data){

}, \);

});

验,获取的分片是否正确,也可以前端传递md5,后台校验;

五、后台获取的log

图:上传的GUID命名的文件夹

图:文件夹下的分片文件

每个分割线包住的地方是一个servlet请求,最后在success请求的servlet是进行文件校验并合并文件即可;代码见下: 六、java文件合并 代码见下:

protectedvoid doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println(\+guid+\+chunks+\

/**

* 进行文件合并 */

File file = new File(path+\+guid); /**

* 判断分片数量是否正确 */

if(file.list().length != chunks){ }

return;

Name=\+fileName);

String guid = request.getParameter(\);

intchunks = Integer.parseInt(request.getParameter(\)); String fileName = request.getParameter(\);

String path =

request.getSession().getServletContext().getRealPath(\);

new File(\+\+guid).mkdir(); /**

* 进行文件合并 */

File newFile = new File(\+\+guid+\+fileName); FileOutputStream outputStream = new FileOutputStream(newFile,

true);//文件追加写入

文件夹以guid命名,数据库储存guid的名字,后期数据移动,只需要更改前端显示的路径; 在这里up遇到一个问题,上传报错:IOException:磁盘空间不足;然而我上传的磁盘还有20G;原因是系统盘空间不足;up重装系统就好了; 注:

1、进度条的显示就很容易了

System.out.println(\+guid+\+chunks+\}

ame=\+fileName);

byte[] byt = newbyte[10*1024*1024]; intlen;

FileInputStream temp = null;//分片文件 for(inti = 0 ; i

* 当所有追加写入都写完 才可以关闭流 */

outputStream.close(); temp.close();

temp = new FileInputStream(new File(path+\+guid+\+i)); while((len = temp.read(byt))!=-1){ }

System.out.println(len);

outputStream.write(byt, 0, len);

引入bootstrap的进度条

60% Complete

now=\aria-valuemin=\aria-valuemax=\style=\width: 0%;\>

2.添加uploadProgress事件监听

uploader.on('uploadProgress', function(file,percentage) {

$(\).css(\,parseInt(percentage*100)+\); });

percentage:当前上传的进度,小数,数值为1是上传完毕; 效果如下:

PS:UI简陋还请见谅!

如果使用过程有问题,可以骚然我,QQ:346640094,Email:lcx1995@foxmail.com;

引入bootstrap的进度条

60% Complete

now=\aria-valuemin=\aria-valuemax=\style=\width: 0%;\>

2.添加uploadProgress事件监听

uploader.on('uploadProgress', function(file,percentage) {

$(\).css(\,parseInt(percentage*100)+\); });

percentage:当前上传的进度,小数,数值为1是上传完毕; 效果如下:

PS:UI简陋还请见谅!

如果使用过程有问题,可以骚然我,QQ:346640094,Email:lcx1995@foxmail.com;

本文来源:https://www.bwwdw.com/article/pqg5.html

Top