摘要:現(xiàn)在要利用這個框架實現(xiàn)上傳文件到服務(wù)端和從服務(wù)端下載文件,然而這個項目用的,默認只支持調(diào)用以基本數(shù)據(jù)類型,以及等常用類型作為參數(shù)和返回值的方法,無法使用這些對象。既然可以傳遞字符串,那就采用文件與字符串互轉(zhuǎn)的方式進行前后交互。
1. 前言
最近在維護一個比較老的 Web 項目,其中用到了 DWR 2.0 (一種可以在 js 里調(diào)用 Java 方法的遠程通信框架)。現(xiàn)在要利用這個框架實現(xiàn)上傳文件到服務(wù)端和從服務(wù)端下載文件,然而這個項目用的 DWR 2.0,默認只支持調(diào)用以基本數(shù)據(jù)類型,以及String、 List、Map 等常用類型作為參數(shù)和返回值的 Java 方法,無法使用 FileTransfer、InputStream、MultipartFile 這些對象。
既然可以傳遞字符串,那就采用文件與字符串互轉(zhuǎn)的方式進行前后交互。流程如下:
上傳文件時,文件 -> ArrayBuffer -> 16 進制字符串 -> byte[] -> 文件
下載文件時,文件 -> byte[] -> 16 進制字符串 -> Uint8Array -> blob -> 文件
HTML 代碼:
JS 代碼:
// 將 ArrayBuffer 轉(zhuǎn)為 16 進制字符串 function bufToHex(buffer) { return Array.prototype.map.call(new Uint8Array(buffer), function (x) { return ("00" + x.toString(16)).slice(-2) }).join("") } function readFilesAndUpload(event) { var processed = 0 var files = event.target.files var len = files.length var filenameArr = new Array(len) // 文件名 var fileContextArr = new Array(len) // 文件內(nèi)容 for (var i = 0; i < len; ++i) { var reader = new FileReader() reader.index = i reader.filename = files[i].name reader.readAsArrayBuffer(files[i]) // 將文件讀到 ArrayBuffer reader.onload = function (e) { filenameArr[this.index] = this.filename fileContextArr[this.index] = bufToHex(this.result) // FileReader 以異步的方式讀取文件,需要借助外部變量判斷是否讀完全部文件 if (++processed === len) { // 將 filenameArr 和 fileContext 上傳到服務(wù)端 } } } }
Java 代碼:
private static final String UPLOAD_DIR = "D://Files/"; public void uploadFiles(List3. 下載文件filenameArr, List fileContextArr) throws IOException { byte[] bytes; FileOutputStream fos; for (int i = 0; i < filenameArr.size(); ++i) { String file = fileContextArr.get(i); // 將 16 進制字符串轉(zhuǎn)換成 byte[] bytes = new byte[file.length() / 2]; for (int j = 0; j < file.length() / 2; ++j) { String subStr = file.substring(j * 2, j * 2 + 2); bytes[j] = (byte) Integer.parseInt(subStr, 16); } // 保存到本地磁盤 fos = new FileOutputStream(UPLOAD_DIR + filenameArr.get(i), true); fos.write(bytes); fos.close(); } }
Java 代碼:
public String downloadFile(String filename) throws IOException { File file = new File(UPLOAD_DIR + filename); if (!file.exists()) { return null; } // 將文件讀到 byte[] byte[] buffer = new byte[(int) file.length()]; InputStream is = new FileInputStream(file); is.read(buffer); is.close(); // 將 byte[] 轉(zhuǎn)換成 16 進制字符串 StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < buffer.length; i++) { int v = buffer[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); }
JS 代碼:
// 16 進制字符串轉(zhuǎn)換成整型數(shù)組 function hexToBytes(hexStr) { var bytes = [] for (var c = 0; c < hexStr.length; c += 2) bytes.push(parseInt(hexStr.substr(c, 2), 16)) return bytes } function downloadFile() { // 調(diào)用服務(wù)端方法,取得 16 進制字符串 res var uint8Array = new Uint8Array(hexToBytes(res)) var blob = new Blob([uint8Array], {type: "application/octet-stream"}) // 兼容 IE、火狐和谷歌的下載方式 if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename) } else { var downloadElement = document.createElement("a") var href = window.URL.createObjectURL(blob) downloadElement.href = href downloadElement.download = filename document.body.appendChild(downloadElement) downloadElement.click() downloadElement.remove() window.URL.revokeObjectURL(href) } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73226.html
摘要:現(xiàn)在要利用這個框架實現(xiàn)上傳文件到服務(wù)端和從服務(wù)端下載文件,然而這個項目用的,默認只支持調(diào)用以基本數(shù)據(jù)類型,以及等常用類型作為參數(shù)和返回值的方法,無法使用這些對象。既然可以傳遞字符串,那就采用文件與字符串互轉(zhuǎn)的方式進行前后交互。 1. 前言 最近在維護一個比較老的 Web 項目,其中用到了 DWR 2.0 (一種可以在 js 里調(diào)用 Java 方法的遠程通信框架)。現(xiàn)在要利用這個框架實現(xiàn)...
摘要:狀態(tài)表示對象的狀態(tài)狀態(tài)描述未初始化。表示成功,表示未找到,表示服務(wù)器內(nèi)部錯誤等。前提是瀏覽器必須支持這個功能,而且服務(wù)器端必須同意這種跨域。事件傳輸成功完成。 系列文章 關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(零)關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(一) ----- XMLHttpRequest關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(二) ----- File關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(三) ----...
摘要:報文用于協(xié)議交互的信息被稱為報文。現(xiàn)在出現(xiàn)的各種首部字段及狀態(tài)碼稍后會闡述。狀態(tài)碼響應(yīng)報文包含了多個范圍的內(nèi)容使用。如果服務(wù)器無法響應(yīng)范圍請求,則會返回狀態(tài)碼和完整的實體內(nèi)容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報文 用于HTTP協(xié)議交互的信息被稱為HTTP報文。請求端的http報文叫做請求報文...
摘要:構(gòu)造函數(shù)創(chuàng)建對象本質(zhì)上和創(chuàng)建一個其他對象的方式是一樣的,都是使用的構(gòu)造函數(shù)來進行創(chuàng)建。構(gòu)造函數(shù)接受兩個參數(shù)第一個參數(shù)為一個數(shù)據(jù)序列,格式可以是第二個參數(shù)是一個包含以下兩個屬性的對象的類型決定第一個參數(shù)的數(shù)據(jù)格式。 Blob,Binary Large Object的縮寫,二進制類型的大對象,代表不可改變的原始數(shù)據(jù) Blob基本用法 Blob對象 Blob對象指的是字節(jié)序列,并且具有siz...
摘要:構(gòu)造函數(shù)創(chuàng)建對象本質(zhì)上和創(chuàng)建一個其他對象的方式是一樣的,都是使用的構(gòu)造函數(shù)來進行創(chuàng)建。構(gòu)造函數(shù)接受兩個參數(shù)第一個參數(shù)為一個數(shù)據(jù)序列,格式可以是第二個參數(shù)是一個包含以下兩個屬性的對象的類型決定第一個參數(shù)的數(shù)據(jù)格式。 Blob,Binary Large Object的縮寫,二進制類型的大對象,代表不可改變的原始數(shù)據(jù) Blob基本用法 Blob對象 Blob對象指的是字節(jié)序列,并且具有siz...
閱讀 3544·2021-09-10 10:51
閱讀 2518·2021-09-07 10:26
閱讀 2495·2021-09-03 10:41
閱讀 821·2019-08-30 15:56
閱讀 2909·2019-08-30 14:16
閱讀 3497·2019-08-30 13:53
閱讀 2113·2019-08-26 13:48
閱讀 1925·2019-08-26 13:37