文件下載案例
1. 要求
- 頁面顯示超鏈接
- 點擊超鏈接后彈出下載提示框
- 完成圖片/視頻文件下載
2. 效果
在這里插入圖片描述
3. 分析
1. 超鏈接指向的資源如果能夠被瀏覽器解析再愈,則在瀏覽器中展示,如果不能解析明肮,則彈出下載提示框艺普。不滿足需求因為任何資源都必須彈出下載提示框
2. 使用響應(yīng)頭設(shè)置資源的打開方式:
* content-disposition:attachment;filename=xxx
3. 文件中文名亂碼
3. 步驟
1. 定義頁面簸州,編輯超鏈接href屬性,指向Servlet歧譬,傳遞資源名稱filename
2. 定義Servlet
1. 獲取文件名稱
2. 使用字節(jié)輸入流加載文件進(jìn)內(nèi)存
3. 指定response的響應(yīng)頭: content-disposition:attachment;filename=xxx
4. 設(shè)置傳輸?shù)臄?shù)據(jù)是什么類型
5. 將數(shù)據(jù)寫出到response輸出流
4. 代碼
在這里插入圖片描述
(1)downLoad.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/day12/downLoadServlet?fileName=2.jpg">下載圖片</a>
<br />
<a href="/day12/downLoadServlet?fileName=1.avi">下載視頻</a>
</body>
</html>
(2)DownLoadServlet.java文件
@WebServlet("/downLoadServlet")
public class DownLoadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.獲取參數(shù)---文件名稱
String fileName = request.getParameter("fileName");
//2.將資源加載進(jìn)內(nèi)存
//2.1 獲取資源的真實路徑
ServletContext servletContext = request.getServletContext();
String path = servletContext.getRealPath("/resource/" + fileName);
//2.2 加載資源
FileInputStream inputStream = new FileInputStream(path);
//3.設(shè)置響應(yīng)頭-以附件形式發(fā)送文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.設(shè)置傳輸?shù)臄?shù)據(jù)是什么類型
String mimeType = servletContext.getMimeType(fileName);
response.setContentType(mimeType);
//5.數(shù)據(jù)傳輸
ServletOutputStream outputStream = response.getOutputStream();
byte[] buff = new byte[1024 * 8]; //字節(jié)緩沖數(shù)組
int len = 0;
while ((len = inputStream.read(buff)) != -1) {
outputStream.write(buff,0,len);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
5. 文件名為中文時亂碼的問題
解決方法:
建立下面文件
在這里插入圖片描述
package cn.wanghao.web.util;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class DownLoadUtils {
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
在以附件形式發(fā)送消息之前岸浑,用DownLoadUtils.getFileName()將文件名轉(zhuǎn)換一下。
代碼如下:
@WebServlet("/downLoadServlet")
public class DownLoadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.獲取參數(shù)---文件名稱
String fileName = request.getParameter("fileName");
//request.setCharacterEncoding()方法對get請求不起作用
//將亂碼轉(zhuǎn)回用ISO8859-1編碼前的二進(jìn)制位
byte[] bytes = fileName.getBytes("ISO8859-1");
//再使用UTF-8進(jìn)行編碼
fileName = new String(bytes,"UTF-8");
//2.將資源加載進(jìn)內(nèi)存
//2.1 獲取資源的真實路徑
ServletContext servletContext = request.getServletContext();
String path = servletContext.getRealPath("/resource/" + fileName);
//2.2 加載資源
FileInputStream inputStream = new FileInputStream(path);
//3.設(shè)置傳輸?shù)臄?shù)據(jù)是什么類型
String mimeType = servletContext.getMimeType(fileName);
response.setContentType(mimeType);
//4.設(shè)置響應(yīng)頭-以附件形式發(fā)送文件
String ua = request.getHeader("user-agent"); //獲取瀏覽器的用戶代理
System.out.println(ua);
fileName = DownLoadUtils.getFileName(ua, fileName);
response.setHeader("content-disposition", "attachment;fileName="+fileName);
//5.數(shù)據(jù)傳輸
ServletOutputStream outputStream = response.getOutputStream();
byte[] buff = new byte[1024 * 8]; //字節(jié)緩沖數(shù)組
int len = 0;
while ((len = inputStream.read(buff)) != -1) {
outputStream.write(buff,0,len);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}