JavaWeb筆記-22-檔案下載
阿新 • • 發佈:2018-11-03
1、檔案下載
下載:向客戶端響應位元組資料。(原來響應的是html的字元資料) 做法:把一個檔案變成位元組陣列,使用response.getOutputStream();來響應給瀏覽器 要求:兩個頭、一個流 Content-Type頭:傳遞給客戶端的MIME型別 使用 this.ServletContext.getMimeType("檔案路徑名")方法,得到MIME型別! 傳參為檔案路徑名 Content-Disposition頭:設定是否彈出下載框。 預設值為inline,表示在瀏覽器視窗開啟 設定值為:attachment;filename=xxx; 表示彈出現在框 filename=後面跟隨的是顯示在下載框中的檔名稱! 流:要下載的檔案資料 new一個輸入流即可 下載步驟: 1)得到兩個頭 Content-Type頭: 使用 this.ServletContext.getMimeType("檔案路徑名")方法,得到MIME型別! 傳參為檔案路徑名 Content-Disposition頭 (設定為彈窗下載,彈窗中顯示處理過編碼的名稱) String contentDisposition = "attachment;filename="+framname; 2)得到資料流 FileInputStream input = new FileInputStream(filename); 3)將兩個頭設定給響應 response.setHeader("Content-Type", contentType); response.setHeader("Content-Disposition", contentDisposition); 4)將流繫結客戶端地址(流往到客戶端) ServletOutputStream output = response.getOutputStream(); 5)把輸入流中的資料寫入到輸出流中 IOUtils.copy(input, output); 下載細節 亂碼問題:當下載框顯示中文名稱時,會出現亂碼 FireFox:Base64編碼 其他瀏覽器:URL編碼。 通用解決方案: filename = new String("需要處理的檔名".getBytes("GBK"),"IOS-8859-1"); 上述方案存在個別特殊字元不能正確顯示 解決:使用方法filenameEncoding
2、程式碼演示:
public class Download1Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 下載歌曲:
* 兩個頭、一個流
* 1.Content-Type
* 2.Content-Disposition
* 3.流:檔案資料流
*/
//得到Content-Type頭
//得到檔案路徑名
String filename = "C:/Users/11316/Music/思疆調.mp3";
//處理檔名亂碼問題
// String newfilename = new String("思疆調.mp3".getBytes("GBK"),"ISO-8859-1");
String framname = filenameEncoding("思疆調.mp3",request);
//通過檔案路徑名稱獲取MIME型別
String contentType = this .getServletContext().getMimeType(filename);
//得到 Content-Disposition頭 (設定為彈窗下載,彈窗中顯示處理過編碼的名稱)
String contentDisposition = "attachment;filename="+framname;
//流 通過檔案路徑名的得到資料流
FileInputStream input = new FileInputStream(filename);
//為響應設定兩個頭: Content-Type、Content-Disposition
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", contentDisposition);
//獲取綁定了客戶端的流(流往到客戶端)
ServletOutputStream output = response.getOutputStream();
//把輸入流中的資料寫入到輸出流中
IOUtils.copy(input, output);
//關閉流
input.close();
}
// 用來對下載的檔名稱進行編碼的! 根據不同瀏覽器不同編碼處理
public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
String agent = request.getHeader("User-Agent"); //獲取瀏覽器
if (agent.contains("Firefox")) {
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";
} else if(agent.contains("MSIE")) {
filename = URLEncoder.encode(filename, "utf-8");
} else {
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
知識點: enctype屬性