java+web+下载断点续传
1、先将 webuploader-0.1.5.zip 这个文件下载下来:https://github.com/fex-team/webuploader/releases
根据个人的需求放置自己需要的东西就行,全部放到项目里也可以,下面是我自己需要的东西:
2、代码部分:分为jsp和servlet部分
1、jsp部分代码:
<script type="text/javascript">
var fileMd5;
//监听分块上传过程中的三个时间点
WebUploader.Uploader.register({
"before-send-file":"beforeSendFile",
"before-send":"beforeSend",
"after-send-file":"afterSendFile",
},{
//时间点1:所有分块进行上传之前调用此函数
beforeSendFile:function(file){
var deferred = WebUploader.Deferred();
//1、计算文件的唯一标记,用于断点续传
(new WebUploader.Uploader()).md5File(file,0,10*1024*1024)
.progress(function(percentage){
$('#item1').find("p.state").text("正在读取文件信息...");
})
.then(function(val){
fileMd5=val;
$('#item1').find("p.state").text("成功获取文件信息...");
//获取文件信息后进入下一步
deferred.resolve();
});
return deferred.promise();
},
//时间点2:如果有分块上传,则每个分块上传之前调用此函数
beforeSend:function(block){
var deferred = WebUploader.Deferred();
$.ajax({
type:"POST",
url:"<%=basePath%>Video?action=checkChunk",
data:{
//文件唯一标记
fileMd5:fileMd5,
//当前分块下标
chunk:block.chunk,
//当前分块大小
chunkSize:block.end-block.start
},
dataType:"json",
success:function(response){
if(response.ifExist){
//分块存在,跳过
deferred.reject();
}else{
//分块不存在或不完整,重新发送该分块内容
deferred.resolve();
}
}
});
this.owner.options.formData.fileMd5 = fileMd5;
deferred.resolve();
return deferred.promise();
},
//时间点3:所有分块上传成功后调用此函数
afterSendFile:function(){
//如果分块上传成功,则通知后台合并分块
$.ajax({
type:"POST",
url:"<%=basePath%>Video?action=mergeChunks",
data:{
fileMd5:fileMd5,
},
success:function(response){
alert("上传成功");
var path = "uploads/"+fileMd5+".mp4";
$("#item1").attr("src",path);
}
});
}
});
var uploader = WebUploader.create({
// swf文件路径
swf: '<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf',
// 文件接收服务端。
server: '<%=basePath%>UploadVideo',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: {id: '#add_video', //这个id是你要点击上传文件的id,自己设置就好
multiple:false},
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: true,
auto:true,
//开启分片上传
chunked: true,
chunkSize:10*1024*1024,
accept: {
//限制上传文件为MP4
extensions: 'mp4',
mimeTypes: 'video/mp4',
}
});
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$('#item1').empty();
$('#item1').html('<div id="' + file.id + '" class="item">'+
'<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+
'<p class="info">' + file.name + '</p>' +
'<p class="state">等待上传...</p></div>'
);
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
});
uploader.on( 'uploadSuccess', function( file ) {
$( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on( 'uploadError', function( file ) {
$( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on( 'uploadComplete', function( file ) {
$( '#'+file.id ).find('.progress').fadeOut();
});
function start(){
uploader.upload();
$('#btn').attr("onclick","stop()");
$('#btn').text("取消上传");
}
function stop(){
uploader.stop(true);
$('#btn').attr("onclick","start()");
$('#btn').text("继续上传");
}
</script>
//这个id是你要点击上传文件的id,自己设置就好
multiple:false},
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: true,
auto:true,
//开启分片上传
chunked: true,
chunkSize:10*1024*1024,
accept: {
//限制上传文件为MP4
extensions: 'mp4',
mimeTypes: 'video/mp4',
}
});
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$('#item1').empty();
$('#item1').html('<div id="' + file.id + '" class="item">'+
'<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+
'<p class="info">' + file.name + '</p>' +
'<p class="state">等待上传...</p></div>'
);
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
});
uploader.on( 'uploadSuccess', function( file ) {
$( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on( 'uploadError', function( file ) {
$( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on( 'uploadComplete', function( file ) {
$( '#'+file.id ).find('.progress').fadeOut();
});
function start(){
uploader.upload();
$('#btn').attr("onclick","stop()");
$('#btn').text("取消上传");
}
function stop(){
uploader.stop(true);
$('#btn').attr("onclick","start()");
$('#btn').text("继续上传");
}
</script>
2、servlet部分代码:
servlet部分需要两个servlet,一个用于接收分块文件,一个用于合并分块成一个文件:
1、接收分块servlet代码:
@SuppressWarnings("serial")
public class UploadVideo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
doPost(req, resp);
}
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory);
sfu.setHeaderEncoding("utf-8");
String savePath = this.getServletConfig().getServletContext()
.getRealPath("");
String folad = "uploads";
savePath = savePath + "\\"+folad+"\\";
String fileMd5 = null;
String chunk = null;
try {
List<FileItem> items = sfu.parseRequest(request);
for(FileItem item:items){
if(item.isFormField()){
String fieldName = item.getFieldName();
if(fieldName.equals("fileMd5")){
fileMd5 = item.getString("utf-8");
}
if(fieldName.equals("chunk")){
chunk = item.getString("utf-8");
}
}else{
File file = new File(savePath+"/"+fileMd5);
if(!file.exists()){
file.mkdir();
}
File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、合并分块servlet代码:
@SuppressWarnings("serial")
public class Video extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet(request, response);
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String savePath = this.getServletConfig().getServletContext()
.getRealPath("");
String folad = "uploads";
savePath = savePath + "\\"+folad+"\\";
String action = request.getParameter("action");
if(action.equals("mergeChunks")){
//合并文件
//需要合并的文件的目录标记
String fileMd5 = request.getParameter("fileMd5");
//读取目录里的所有文件
File f = new File(savePath+"/"+fileMd5);
File[] fileArray = f.listFiles(new FileFilter(){
//排除目录只要文件
@Override
public boolean accept(File pathname) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated method stub
if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
return -1;
}
return 1;
}
});
//UUID.randomUUID().toString()-->随机名
File outputFile = new File(savePath+"/"+fileMd5+".mp4");
//创建文件
outputFile.createNewFile();
//输出流
FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
//合并
FileChannel inChannel;
for(File file : fileList){
inChannel = new FileInputStream(file).getChannel();
inChannel.transferTo(0, inChannel.size(), outChnnel);
inChannel.close();
//删除分片
file.delete();
}
outChnnel.close();
//清除文件夹
File tempFile = new File(savePath+"/"+fileMd5);
if(tempFile.isDirectory() && tempFile.exists()){
tempFile.delete();
}
System.out.println("合并成功");
}else if(action.equals("checkChunk")){
//检查当前分块是否上传成功
String fileMd5 = request.getParameter("fileMd5");
String chunk = request.getParameter("chunk");
String chunkSize = request.getParameter("chunkSize");
File checkFile = new File(savePath+"/"+fileMd5+"/"+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}");
}
}
}
}
至此,大文件上传的分块和断点就ok了,这也只是我自己的项目需求编写的,这个框架还涵盖很多的内容和功能,需要你自己去研究了,不过都不是很难,你也可以去修改它的css和js文件根据自己的需求。
详细的配置信息可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/06/14/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd%e6%96%87%e4%bb%b6%e5%88%b0%e6%8c%87%e5%ae%9a%e6%96%87%e4%bb%b6%e5%a4%b9/
java+web+下载断点续传的更多相关文章
- java web 下载文件 response.setHeader()的用法 (转载)
response.setHeader()的用法 response.setHeader()下载中文文件名乱码问题 收藏 1. HTTP消息头 (1)通用信息头 即能用于请求消息中,也能用于响应信息中,但 ...
- 关于java WEB下载
web.xml配置mapping 页面直接配置路径就可下载 <mime-mapping> <extension>doc</extension> <mim ...
- java web 下载本地文件并弹出下载框
window.open("/dept/download") jsp代码 @RequestMapping(value = "/download", method ...
- java多线程下载和断点续传
java多线程下载和断点续传,示例代码只实现了多线程,断点只做了介绍.但是实际测试结果不是很理想,不知道是哪里出了问题.所以贴上来请高手修正. [Java]代码 import java.io.File ...
- JAVA Web 之 struts2文件上传下载演示(二)(转)
JAVA Web 之 struts2文件上传下载演示(二) 一.文件上传演示 详细查看本人的另一篇博客 http://titanseason.iteye.com/blog/1489397 二.文件下载 ...
- JAVA Web 之 struts2文件上传下载演示(一)(转)
JAVA Web 之 struts2文件上传下载演示(一) 一.文件上传演示 1.需要的jar包 大多数的jar包都是struts里面的,大家把jar包直接复制到WebContent/WEB-INF/ ...
- 初学Java Web(7)——文件的上传和下载
文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...
- 解决java web中safari浏览器下载后文件中文乱码问题
解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...
- maven的下载,安装配置以及build一个java web项目
一.下载 下载地址:http://maven.apache.org/download.cgi 二.安装 下载完成后,解压,进入到bin目录: 三.环境变量配置 复制bin目录下的文件的路径(如:xxx ...
随机推荐
- Jmeter-后置处理器--json提取器
Token提取: 将token放入全局变量: 将token值设为全局变量,${__setProperty(newtoken,${token},)} 添加请求头部管理器作为全局使用,将变量token使 ...
- SQLSERVER查询存储过程内容
--使用语句查看一个存储过程的定义 EXEC sp_helptext 'Auth_BankCardAuthorize' --查询所有存储过程的名称以及定义 SELECT name, definitio ...
- SVN_02安裝
1.下载 TortoiseSVN https://tortoisesvn.net/downloads.html 2.下载 VIsualSVN https://www.visualsvn.com ...
- Go net/http 发送常见的 http 请求
使用 golang 中的 net/http 包来发送和接收 http 请求 开启 web server 先实现一个简单的 http server,用来接收请求 package main import ...
- vue的data里面的值是数组时,在更改其某一项的时候,怎么触发视图的重新渲染?
1. 设置对象或数组的值:Vue.set(target,key,value) :2.删除对象或数组中元素: Vue.delete ( target,key) ;3. 数组对象直接修改属性,可以触发视图 ...
- How to delete SAP* from HANA Tenant database
How to delete SAP* from HANA Tenant database 1.如何登录HANA的多租户(TDC)数据库 使用SAPS4端对应的SAP账户,比如S4D的账户为s4dadm ...
- weblogic jdbc 相关概念介绍
weblogic jdbc 是什么? 如何配置? 常见问题? 如何监控?
- 如何实现高性能的IO及其原理?
程序运行在内存以及IO的体现 首先普及一下常识,如图所示: 1.在整个内存空间中,跑着各种各样的程序,有Java程序.C程序,他们共用一块内存空间. 2.对于Java程序,JVM会申请一块堆空间,通过 ...
- Nginx作为缓存服务
缓存类型 (1) 服务器缓存 服务端缓存一般使用Memcache.Redis (2)代理缓存 (3)客户端缓存 代理缓存流程图 第一步:客户端第一次向Nginx请求数据a: 第二步:当Nginx发现缓 ...
- C# - 配置动态更新
生产中经常会遇到修改配置的情况,但是又需要重启应用程序,是不是有点小烦躁.... 下面了解下在不重启情况下,实现配置更新实时生效 public static void SetConfig(string ...