普通下載功能的實現(xiàn)
FileInputStream inputStream = null;
ServletOutputStream os = null;
try {
inputStream = new FileInputStream(file);
//設(shè)置響應(yīng)狀態(tài)200
response.setStatus(HttpServletResponse.SC_OK);
//設(shè)置內(nèi)容類型
response.setContentType(getContentType(fileId));
//添加響應(yīng)頭 設(shè)置內(nèi)容長度
response.addHeader("Content-Length", String.valueOf(file.length()));
//添加響應(yīng)頭 設(shè)置允許瀏覽器可嘗試恢復(fù)中斷的下載
response.addHeader("Accept-Ranges", "bytes");
response.addHeader("Cache-control", "private");
//添加響應(yīng)頭 設(shè)置瀏覽器另存為對話框的默認(rèn)文件名
response.addHeader("Content-Disposition", "filename=" + file.getName());
response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");
os = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) != -1) {
os.write(buf, 0, len);
os.flush();
}
} catch (Exception e) {
//操作文件失敗時返回響應(yīng)狀態(tài) 500
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
} finally {
//結(jié)束后釋放資源
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
支持分片下載功能的實現(xiàn)
- 這里是因為測試中ios safari 瀏覽器無法正常打開播放視頻文件,通過抓取分析瀏覽器訪問靜態(tài)資源視頻過程實現(xiàn)的代碼
//獲取請求頭
String range = request.getHeader("range");
String referer = request.getHeader("referer");
//處理range 計算請求的哪部分?jǐn)?shù)據(jù)
String[] split = range.split("bytes=|-");
long begin = 0;
if (split.length >= 2) {
begin = Long.valueOf(split[1]);
}
long end = file.length() - 1;
if (split.length >= 3) {
end = Long.valueOf(split[2]);
}
long len = (end - begin) + 1;
//如果請求的文件長度超過文件實際長度 返回錯誤狀態(tài)
if (end > file.length()) {
//返回狀態(tài) 500
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
FileInputStream inputStream = null;
ServletOutputStream os = null;
try {
//創(chuàng)建文件流
inputStream = new FileInputStream(file);
//將指針移到請求片段的開始位置
inputStream.skip(begin);
//設(shè)置響應(yīng)狀態(tài) 206 部分內(nèi)容
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
//設(shè)置內(nèi)容類型
response.setContentType(getContentType(fileId));
//添加響應(yīng)頭 設(shè)置片段開始位置 結(jié)束位置 文件總長度
response.addHeader("Content-Range", "bytes " + begin + "-" + end + "/" + file.length());
//添加響應(yīng)頭 設(shè)置響應(yīng)片段的長度
response.addHeader("Content-Length", String.valueOf(len));
//添加響應(yīng)頭 設(shè)置允許瀏覽器可嘗試恢復(fù)中斷的下載
response.addHeader("Accept-Ranges", "bytes");
response.addHeader("Cache-control", "private");
//添加響應(yīng)頭 設(shè)置瀏覽器另存為對話框的默認(rèn)文件名
response.addHeader("Content-Disposition", "filename=" + file.getName());
response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");
os = response.getOutputStream();
//從文件流中讀指定長度的片段輸出
byte[] buf = new byte[1024];
while (len > 0) {
inputStream.read(buf);
long l = len > 1024 ? 1024 : len;
os.write(buf, 0, (int) l);
os.flush();
len -= l;
}
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
} finally {
//釋放資源
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Github
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。