1. 程式人生 > 其它 >java上傳資料夾到oss

java上傳資料夾到oss

javaweb上傳檔案

上傳檔案的jsp中的部分

上傳檔案同樣可以使用form表單向後端發請求,也可以使用 ajax向後端發請求

1.通過form表單向後端傳送請求

<form id="postForm" action="${pageContext.request.contextPath}/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 : "${pageContext.request.contextPath}/UploadServlet",

type : "POST",

data : $( '#postForm').serialize(),

success : function(data) {

$( '#serverResponse').html(data);

},

error : function(data) {

$( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);

}

});

ajax分為兩部分,一部分是初始化,檔案在上傳前通過AJAX請求通知服務端進行初始化操作

this.md5_complete =function(json)

{

this.fileSvr.md5 = json.md5;

this.ui.msg.text("MD5計算完畢,開始連線伺服器...");

this.event.md5Complete(this, json.md5);//biz event

varloc_path = encodeURIComponent(this.fileSvr.pathLoc);

varloc_len =this.fileSvr.lenLoc;

varloc_size =this.fileSvr.sizeLoc;

varparam = jQuery.extend({},this.fields,this.Config.bizData, { md5: json.md5, id:this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time:newDate().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資訊錯誤!"+ req.responseText);

_this.ui.msg.text("向伺服器傳送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.fileSvr.complete =true;

$.each(this.ui.btn,function(i, n)

{

n.hide();

});

this.ui.process.css("width","100%");

this.ui.percent.text("(100%)");

this.ui.msg.text("上傳完成");

this.Manager.arrFilesComplete.push(this);

this.State =this.Config.state.Complete;

//從上傳列表中刪除

this.Manager.RemoveQueuePost(this.fileSvr.id);

//從未上傳列表中刪除

this.Manager.RemoveQueueWait(this.fileSvr.id);

varparam = { md5:this.fileSvr.md5, uid:this.uid, id:this.fileSvr.id, time:newDate().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資訊錯誤!"+ req.responseText); }

, complete:function(req, sta) { req =null; }

});

};

這裡需要處理一個MD5秒傳的邏輯,當伺服器存在相同檔案時,不需要使用者再上傳,而是直接通知使用者秒傳

this.post_complete_quick =function()

{

this.fileSvr.perSvr ="100%";

this.fileSvr.complete =true;

this.ui.btn.stop.hide();

this.ui.process.css("width","100%");

this.ui.percent.text("(100%)");

this.ui.msg.text("伺服器存在相同檔案,快速上傳成功。");

this.Manager.arrFilesComplete.push(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:"${pageContext.request.contextPath}/UploadServlet",

type:"post",

data:form,

processData:false,

contentType:false,

success:function(data){

console.log(data);

}

});

java部分

檔案初始化的邏輯,主要程式碼如下

FileInf fileSvr=newFileInf();

fileSvr.id = id;

fileSvr.fdChild =false;

fileSvr.uid = Integer.parseInt(uid);

fileSvr.nameLoc = PathTool.getName(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 =newPathBuilderUuid();

fileSvr.pathSvr = pb.genFile(fileSvr.uid,fileSvr);

fileSvr.pathSvr = fileSvr.pathSvr.replace("\\","/");

DBConfig cfg =newDBConfig();

DBFile db = cfg.db();

FileInf fileExist =newFileInf();

booleanexist = 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;

fileSvr.complete= fileExist.complete;

db.Add(fileSvr);

//觸發事件

up6_biz_event.file_create_same(fileSvr);

}//此檔案不存在

else

{

db.Add(fileSvr);

//觸發事件

up6_biz_event.file_create(fileSvr);

FileBlockWriter fr =newFileBlockWriter();

fr.CreateFile(fileSvr.pathSvr,fileSvr.lenLoc);

}

接收檔案塊資料,在這個邏輯中我們接收檔案塊資料。控制元件對資料進行了優化,可以方便除錯。如果用監控工具可以看到控制元件提交的資料。

booleanisMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory =newDiskFileItemFactory();

ServletFileUpload upload =newServletFileUpload(factory);

List files =null;

try

{

files = upload.parseRequest(request);

}

catch(FileUploadException e)

{//解析檔案資料錯誤

out.println("read file data error:"+ e.toString());

return;

}

FileItem rangeFile =null;

//得到所有上傳的檔案

Iterator fileItr = files.iterator();

//迴圈處理所有檔案

while(fileItr.hasNext())

{

//得到當前檔案

rangeFile = (FileItem) fileItr.next();

if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))

{

pathSvr = rangeFile.getString();

pathSvr = PathTool.url_decode(pathSvr);

}

}

booleanverify =false;

String msg ="";

String md5Svr ="";

longblockSizeSvr = rangeFile.getSize();

if(!StringUtils.isBlank(blockMd5))

{

md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());

}

verify = Integer.parseInt(blockSize) == blockSizeSvr;

if(!verify)

{

msg ="block size error sizeSvr:"+ blockSizeSvr +"sizeLoc:"+ blockSize;

}

if(verify && !StringUtils.isBlank(blockMd5))

{

verify = md5Svr.equals(blockMd5);

if(!verify) msg ="block md5 error";

}

if(verify)

{

//儲存檔案塊資料

FileBlockWriter res =newFileBlockWriter();

//僅第一塊建立

if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));

res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));

JSONObject o =newJSONObject();

o.put("msg","ok");

o.put("md5", md5Svr);

o.put("offset", blockOffset);//基於檔案的塊偏移位置

msg = o.toString();

}

rangeFile.delete();

out.write(msg);

注:

1.上面的java部分的程式碼可以直接使用,只需要將上傳的圖片路徑及收集資料並將資料寫入到資料庫即可

2.上面上傳檔案使用到了位元組流,其實還可以使用別的流,這個需要讀者自己在下面完善測試

3. BeanUtils是一個工具 便於將實體對應的屬性賦給實體

4.上傳檔案不能使用 request.getParameter("")獲取引數了,而是直接將request解析,通過判斷每一項是檔案還是非檔案,然後進行相應的操作(檔案的話就是用流來讀取,非檔案的話,暫時儲存到一個map中。)

後端程式碼邏輯大部分是相同的,目前能夠支援MySQL,Oracle,SQL。在使用前需要配置一下資料庫,可以參考我寫的這篇文章:java http大檔案斷點續傳上傳 – 澤優軟體部落格
歡迎入群一起討論“374992201”