JAVAWEB项⽬⼤⽂件上传下载解决⽅案
javaweb上传⽂件
上传⽂件的jsp中的部分
上传⽂件同样可以使⽤form表单向后端发请求,也可以使⽤ ajax向后端发请求
1.通过form表单向后端发送请求
<form id="postForm" action="${tPath}/UploadServlet" method="post" enctype="multipart/form-data">            <div class="bbxx wrap">
<inputtype="text" id="side-profile-name" name="username" class="form-control">
<inputtype="file" id="example-file-input" name="avatar">
<button type="submit" class="btn btn-effect-ripple btn-primary">Save</button>
</div>
</form>
改进后的代码不需要form标签,直接由控件来实现。开发⼈员只需要关注业务逻辑即可。JS中已经帮我们封闭好了
this.post_file = function ()
{
$.each(this.ui.btn, function (i, n) { n.hide();});
this.ui.btn.stop.show();
this.State = this.Config.state.Posting;//
this.app.postFile({ id: this.fileSvr.id, pathLoc: this.fileSvr.pathLoc, pathSvr:this.fileSvr.pathSvr,lenSvr: this.fileSvr.lenSvr, fields: this.fields });
};
通过监控⼯具可以看到控件提交的数据,⾮常的清晰,调试也⾮常的简单。
2.通过ajax向后端发送请求
$.ajax({
url : "${tPath}/UploadServlet",
type : "POST",
data : $( '#postForm').serialize(),
success : function(data) {
$( '#serverResponse').html(data);
},
error : function(data) {
$( '#serverResponse').html(data.status + " : " + data.statusText + " : " + sponseText);
}
});
ajax分为两部分,⼀部分是初始化,⽂件在上传前通过AJAX请求通知服务端进⾏初始化操作
this.md5_complete = function (json)
{
this.fileSvr.md5 = json.md5;
this.("MD5计算完毕,开始连接服务器...");
this.event.md5Complete(this, json.md5);//biz event
var loc_path = encodeURIComponent(this.fileSvr.pathLoc);
var loc_len = this.fileSvr.lenLoc;
var loc_size = this.fileSvr.sizeLoc;
var param = d({}, this.fields, this.Config.bizData, { md5: json.md5, id: this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time: new Date().getTime() });
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //⾃定义的jsonp回调函数名称,默认为jQuery⾃动⽣成的随机函数名
, url: this.Config["UrlCreate"]
, data: param
, success: function (sv)
{
_this.svr_create(sv);
}
, error: function (req, txt, err)
{
_this.Manager.RemoveQueuePost(_this.fileSvr.id);
alert("向服务器发送MD5信息错误!" + sponseText);
_this.("向服务器发送MD5信息错误");
_this.ui.btn.cancel.show();
_this.ui.btn.stop.hide();
}
, complete: function (req, sta) { req = null; }
});
};
在⽂件上传完后向服务器发送通知
this.post_complete = function (json)
{
this.fileSvr.perSvr = "100%";
this.fileSvrplete = true;
$.each(this.ui.btn, function (i, n)
{
});
this.ui.process.css("width", "100%");
this.("(100%)");
this.("上传完成");
this.Manager.arrFilesComplete.push(this);
this.State = this.Config.state.Complete;
/
/从上传列表中删除
this.Manager.RemoveQueuePost(this.fileSvr.id);
//从未上传列表中删除
this.Manager.RemoveQueueWait(this.fileSvr.id);
var param = { md5: this.fileSvr.md5, uid: this.uid, id: this.fileSvr.id, time: new Date().getTime() };
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //⾃定义的jsonp回调函数名称,默认为jQuery⾃动⽣成的随机函数名
, url: _this.Config["UrlComplete"]
, data: param
,
success: function (msg)
{
_this.event.fileComplete(_this);//触发事件
_this.post_next();
}
, error: function (req, txt, err) { alert("⽂件-向服务器发送Complete信息错误!" + sponseText); }              , complete: function (req, sta) { req = null; }
});
};
这⾥需要处理⼀个MD5秒传的逻辑,当服务器存在相同⽂件时,不需要⽤户再上传,⽽是直接通知⽤户秒传    this.post_complete_quick = function ()
{
this.fileSvr.perSvr = "100%";
this.fileSvrplete = true;
this.ui.btn.stop.hide();
this.ui.process.css("width", "100%");
this.("(100%)");
this.("服务器存在相同⽂件,快速上传成功。");
this.State = this.Config.state.Complete;
//从上传列表中删除
this.Manager.RemoveQueuePost(this.fileSvr.id);
//从未上传列表中删除
this.Manager.RemoveQueueWait(this.fileSvr.id);
/
/添加到⽂件列表
this.post_next();
this.event.fileComplete(this);//触发事件
};
这⾥可以看到秒传的逻辑是⾮常简单的,并不是特别的复杂。
var form = new FormData();
form.append("username","zxj");
form.append("avatar",file);
//var form = new FormData($("#postForm")[0]);
$.ajax({
url:"${tPath}/UploadServlet",                type:"post",
data:form,
processData:false,
contentType:false,
success:function(data){
console.log(data);
}
});
java部分
⽂件初始化的逻辑,主要代码如下
FileInf fileSvr= new FileInf();
fileSvr.id = id;
fileSvr.fdChild = false;
fileSvr.uid = Integer.parseInt(uid);
大文件发送fileSvr.nameLoc = Name(pathLoc);
fileSvr.pathLoc = pathLoc;
fileSvr.lenLoc = Long.parseLong(lenLoc);
fileSvr.sizeLoc = sizeLoc;
fileSvr.deleted = false;
fileSvr.md5 = md5;
fileSvr.nameSvr = fileSvr.nameLoc;
//所有单个⽂件均以uuid/file⽅式存储
PathBuilderUuid pb = new PathBuilderUuid();
fileSvr.pathSvr = pb.genFile(fileSvr.uid,fileSvr);
fileSvr.pathSvr = place("\\","/");
DBConfig cfg = new DBConfig();
DBFile db = cfg.db();
FileInf fileExist = new FileInf();
boolean exist = db.exist_file(md5,fileExist);
//数据库已存在相同⽂件,且有上传进度,则直接使⽤此信息
if(exist && fileExist.lenSvr > 1)
{
fileSvr.nameSvr            = fileExist.nameSvr;
fileSvr.pathSvr        = fileExist.pathSvr;
fileSvr.perSvr              = fileExist.perSvr;
fileSvr.lenSvr              = fileExist.lenSvr;
fileSvrplete      = fileExistplete;
db.Add(fileSvr);
//触发事件
up6_biz_event.file_create_same(fileSvr);
}//此⽂件不存在
else
{
db.Add(fileSvr);
//触发事件
up6_biz_event.file_create(fileSvr);
FileBlockWriter fr = new FileBlockWriter();
fr.CreateFile(fileSvr.pathSvr,fileSvr.lenLoc);
}
接收⽂件块数据,在这个逻辑中我们接收⽂件块数据。控件对数据进⾏了优化,可以⽅便调试。如果⽤监控⼯具可以看到控件提交的数据。boolean isMultipart = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List files = null;
try