java get方式異步上傳_簡(jiǎn)述Java異步上傳文件的三種方式 原創(chuàng)
創(chuàng)新互聯(lián)建站是一家專業(yè)提供岢嵐企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)、H5開(kāi)發(fā)、小程序制作等業(yè)務(wù)。10年已為岢嵐眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
2021-02-13 16:31:03
yi bbbian
碼齡4年
關(guān)注
本文為大家分享了三種Java異步上傳文件方式,供大家參考,具體內(nèi)容如下
用第三方控件,如Flash,ActiveX等瀏覽器插件上傳。
使用隱藏的iframe模擬異步上傳。
使用XMLHttpRequest2來(lái)實(shí)現(xiàn)異步上傳。
第一種使用瀏覽器插件上傳,需要一定的底層編碼功底,在這里我就不講了,以免誤人子弟,提出這點(diǎn)大家可以自行百度。
第二種使用隱藏的iframe模擬異步上傳。為什么在這里說(shuō)的是模擬呢?因?yàn)槲覀兤鋵?shí)是將返回結(jié)果放在了一個(gè)隱藏的iframe中,所以才沒(méi)有使當(dāng)前頁(yè)面跳轉(zhuǎn),感覺(jué)就像是異步操作一樣。
隱藏的iframe上傳文件
附件:
正在上傳...
// 上傳完成后的回調(diào)
function uploadFinished(fileName) {
addToFlist(fileName);
loading(false);
}
function addToFlist(fname) {
var temp = ["
",
fname,
"刪除",
"
"
];
$("#flist").append(temp.join(""));
}
function loading(showloading) {
if (showloading) {
$("#uptxt").show();
} else {
$("#uptxt").hide;
}
}
這種技術(shù)有兩個(gè)關(guān)鍵的地方:
1.form會(huì)指定target,提交的結(jié)果定向返回到隱藏的ifram中。(即form的target與iframe的name屬性一致)。
2.提交完成后,iframe中頁(yè)面與主頁(yè)面通信,通知上傳結(jié)果及服務(wù)端文件信息
如何與主頁(yè)面通信呢?
我們用nodejs在接收完了文件后返回了一個(gè)window.parent.主頁(yè)面定義的方法,執(zhí)行后可以得知文件上傳完成。代碼很簡(jiǎn)單:
router.post('/upload2', multipartMiddleware, function(req, res) {
var fpath = req.files.myfile.path;
var fname = fpath.substr(fpath.lastIndexOf('\\') + 1);
setTimeout(function {
var ret = ["
"window.parent.uploadFinished('" + fname + "');",
""];
res.send(ret.join(""));
}, 3000);
});
執(zhí)行后可以打開(kāi)開(kāi)發(fā)人員選項(xiàng),你會(huì)發(fā)現(xiàn)隱藏iframe中返回了服務(wù)器的一些數(shù)據(jù)。
第三種使用XMLHttpRequest2來(lái)進(jìn)行真正的異步上傳。
還是先貼出代碼:
執(zhí)行后可以打開(kāi)開(kāi)發(fā)人員選項(xiàng),你會(huì)發(fā)現(xiàn)隱藏iframe中返回了服務(wù)器的一些數(shù)據(jù)。第三種使用XMLHttpRequest2來(lái)進(jìn)行真正的異步上傳。還是先貼出代碼:
xhr level2 異步上傳
附件:
正在上傳...
停止上傳
function upload {
// 1.準(zhǔn)備FormData
var fd = new FormData;
fd.append("myfile", $("#myfile")[0].files[0]);
// 創(chuàng)建xhr對(duì)象
var xhr = new XMLHttpRequest;
// 監(jiān)聽(tīng)狀態(tài),實(shí)時(shí)響應(yīng)
// xhr 和 xhr.upload 都有progress事件,xhr.progress是下載進(jìn)度,xhr.upload.progress是上傳進(jìn)度
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
var percent = Math.round(event.loaded * 100 / event.total);
console.log('%d%', percent);
$("#upprog").text(percent);
}
};
// 傳輸開(kāi)始事件
xhr.onloadstart = function(event) {
console.log('load start');
$("#upprog").text('開(kāi)始上傳');
$("#stopbtn").one('click', function { xhr.abort; $(this).hide();});
loading(true);
};
// ajax過(guò)程成功完成事件
xhr.onload = function(event) {
console.log('load success');
$("#upprog").text('上傳成功');
console.log(xhr.responseText);
var ret = JSON.parse(xhr.responseText);
addToFlist(ret.fname);
};
// ajax過(guò)程發(fā)生錯(cuò)誤事件
xhr.onerror = function(event) {
console.log('error');
$("#upprog").text('發(fā)生錯(cuò)誤');
};
// ajax被取消
xhr.onabort = function(event) {
console.log('abort');
$("#upprog").text('操作被取消');
};
// loadend傳輸結(jié)束,不管成功失敗都會(huì)被觸發(fā)
xhr.onloadend = function (event) {
console.log('load end');
loading(false);
};
// 發(fā)起ajax請(qǐng)求傳送數(shù)據(jù)
xhr.open('POST', '/upload3', true);
xhr.send(fd);
}
function addToFlist(fname) {
var temp = ["
",
fname,
"刪除",
"
"
];
$("#flist").append(temp.join(""));
}
function delFile(fname) {
console.log('to delete file: ' + fname);
// TODO: 請(qǐng)實(shí)現(xiàn)
}
function loading(showloading) {
if (showloading) {
$("#uptxt").show();
$("#stopbtn").show();
} else {
$("#uptxt").hide();
$("#stopbtn").hide();
}
}
代碼有點(diǎn)多,但是通俗易懂。使用過(guò)AJAX的人都知道,XHR對(duì)象提供了一個(gè)onreadystatechange的回調(diào)方法來(lái)監(jiān)聽(tīng)整個(gè)請(qǐng)求/響應(yīng)過(guò)程。在XMLHttpRequest2級(jí)規(guī)范中又多了幾個(gè)進(jìn)度事件。有以下6個(gè)事件:
1.loadstart:在接收到響應(yīng)數(shù)據(jù)的第一個(gè)字節(jié)時(shí)觸發(fā)。
2.progress:在接收響應(yīng)期間持續(xù)不斷地觸發(fā)。
3.error:在請(qǐng)求發(fā)生錯(cuò)誤時(shí)觸發(fā)。
4.abort:在因?yàn)檎{(diào)用abort方法而終止連接時(shí)觸發(fā)。
5.load:在接收到完整的響應(yīng)數(shù)據(jù)時(shí)觸發(fā)。
6.loadend: 在通信完成或者觸發(fā)error,abort,load事件后觸發(fā)。
這次我們可以解讀代碼:當(dāng)傳輸事件開(kāi)始后,我們便在停止傳送按鈕上添加點(diǎn)擊事件,內(nèi)置了abort方法可以停止傳送。若不點(diǎn)則會(huì)正常上傳直到傳送完畢為止。其后臺(tái)代碼類似第二種方法。
三種方法各有優(yōu)劣,做個(gè)簡(jiǎn)單的小結(jié)吧。
第三方控件交互性和可控性好,因?yàn)榻咏讓?,其性能也是很?yōu)秀的。但是由于編寫難度大通常需要自己安裝插件,有時(shí)可能需要自己進(jìn)行編寫。
隱藏的iframe方法我個(gè)人覺(jué)得是非常有思想的一個(gè)方法,iframe可以幫我們做很多事。這種方式具有廣泛的瀏覽器兼容性而且不需要安裝插件。但是它交互性差,上傳過(guò)程不可控,而且性能也是很一般的。
XHR2級(jí)的純ajax上傳,它必須要版本比較高一點(diǎn)的瀏覽器(ie9+)。但是它交互性特別好,可以看到上傳進(jìn)度并且是可控的。
JButton
button=new
JButton();
button.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
arg0)
{
//這里就是偵聽(tīng)后觸發(fā)事件處理的代碼部分
//比如說(shuō)你要觸發(fā)的另一個(gè)class類名為NewWindow,是繼承自JFrame的窗體class
//那么如下代碼就可以了
NewWindow
newWindow=new
NewWindow();
newWindow.setVisible(true);
//這樣就實(shí)現(xiàn)該按鈕觸發(fā)新的class程序NewWindow了
}
}
//最后將這個(gè)按鈕添加到容器面板里,運(yùn)行的時(shí)候這個(gè)按鈕就會(huì)開(kāi)始生效了
該段代碼簡(jiǎn)單實(shí)用,完全滿足樓主的情況和要求
java中,按鈕點(diǎn)擊時(shí)會(huì)觸發(fā)你的點(diǎn)擊函數(shù)onclick,你在點(diǎn)擊的函數(shù)中寫你的代碼就可以了,比如你說(shuō)的跳轉(zhuǎn)另一個(gè)面板。
Java提供了兩個(gè)事件偵聽(tīng)接口用來(lái)管理鼠標(biāo)移動(dòng)和鍵盤動(dòng)作,分別是MouseMotionListener和KeyListener,可以用它們來(lái)捕捉鼠標(biāo)和鍵盤。
1)類KeyMonitor,是一個(gè)JPanel的擴(kuò)展類,用來(lái)顯示捕捉到的按鍵信息;
2)類MouseMonitor,也是一個(gè)JPanel的擴(kuò)展類,用來(lái)顯示到的鼠標(biāo)移動(dòng)信息;
3)入口類Main,用匿名類的方式實(shí)現(xiàn)了真正的監(jiān)聽(tīng)接口;
PS:Java提供的這兩個(gè)偵聽(tīng)器都有很大的限制,鼠標(biāo)監(jiān)聽(tīng)只有在鼠標(biāo)位于Java程序所在的窗口范圍之內(nèi)才能有效,而鍵盤監(jiān)聽(tīng)限制更嚴(yán)格,僅當(dāng)Java程序成為當(dāng)前的活動(dòng)窗口時(shí)才有效。單純用Java來(lái)實(shí)現(xiàn)全屏幕、所有程序的鼠標(biāo)和鍵盤活動(dòng)是不可行的。