Java文件下载/下载文件的案例
文章目錄
- 需求
- 分析
- 實現步驟
- 示例代碼
- 下載的文件中文名顯示問題
需求
1.頁面顯示超鏈接
2.點擊超鏈接后彈出下載對話框
3.完成圖片文件下載
分析
超鏈接指向的資源如果能夠被瀏覽器解析,則直接在瀏覽器中展示,如果不能解析,則彈出下載提示框。如果希望無論返回什么資源都不要解析,而是讓用戶下載,那么就必須使用 content-disposition 響應頭告訴客戶端,返回的資源(響應體的數據)以附件的形式打開。
實現步驟
1.開發前端頁面,使用超鏈接標簽,href 屬性指向一個 Servlet,并且傳遞下載資源的名稱
2.實現后端邏輯,定義一個 Servlet,獲取下載資源的名稱,再根據資源名稱將對應的資源加載入內存中,再從內存輸出到 Response對象中,再返回給客戶端
2.1.獲取參數
2.2.使用字節輸入流讀取資源文件,加載進內存中
2.3.設置響應頭(content-type 和 content-disposition)
2.4.使用字節輸出流寫入到 Response 對象中。具體是從內存寫入到 Response 的字節輸出流中,再從字節輸出流寫入到 Response 對象中
2.5.服務器從 Response 對象中獲取數據構建成響應報文發送給客戶端(這步服務器自動完成)
說明:
response.setHeader("content-disposition", "attachement;filename=123.jpeg");上述代碼表示將響應頭 content-disposition 的值設為 attachement;filename=123.jpeg。其中 attachement 表示響應的資源以附件形式打開;filename 是彈出的下載對話框中顯示的文件名稱以及文件下載后的文件名稱。
示例代碼
前端頁面示例代碼:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <a href="/servlet_demo/download?fileName=1.jpeg">圖片</a> <a href="/servlet_demo/download?fileName=1.avi">視頻</a> </body> </html>服務端示例代碼:
package priv.lwx.javaex.servlet_demo.web.servlet.download; /*** description** @author liaowenxiong* @date 2022/1/12 21:57*/import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException;@WebServlet("/download") public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.獲取請求參數fileNameString fileName = request.getParameter("fileName");// 2.使用字節輸入流加載文件進內存// 2.1.獲取文件的服務器路徑String realPath = this.getServletContext().getRealPath("/image/" + fileName);// 2.2.獲取文件的文件字節輸入流(用文件字節流關聯文件)FileInputStream fis = new FileInputStream(realPath); // 這步就完成了讀取文件數據進內存的操作System.out.println(fis);// 3.設置響應頭// 3.1.設置響應頭content-typeServletContext context = this.getServletContext();// 獲取文件的MIME類型String mimeType = context.getMimeType(fileName);// 告訴客戶端響應體的數據類型response.setHeader("content-type", mimeType);// 3.2.設置響應頭content-dispositionresponse.setHeader("content-disposition", "attachement;filename=" + fileName);// 4.將輸入流的數據寫入到輸出流中(類似文件復制的操作)// 4.1.獲取字節輸出流ServletOutputStream sos = response.getOutputStream();// 4.2.定義讀取到的字節數據的緩沖區byte[] buff = new byte[1024 * 8];int len = 0;// 將字節數據讀取到字節數組中,返回讀取到的字節數,如果返回的字節數不是-1,說明沒有讀到文件末尾// 注意:字節輸入流每次讀取到字節數組中的數據會覆蓋原來的舊數據while ((len = fis.read(buff)) != -1) {// 將字節數組中的字節數據寫入到字節輸出流中,sos.write(buff, 0, len);}// 5.釋放資源fis.close();} }下載的文件中文名顯示問題
如果你下載的文件名稱是中文,不同瀏覽器版本會有不同的顯示,不過都是錯誤的顯示。
解決的辦法:判斷瀏覽器的版本,根據不同的瀏覽器版本對文件名進行不同的編碼,再返回給客戶端顯示。
處理文件名稱的示例代碼如下:
package priv.lwx.javaex.servlet_demo.util;import Decoder.BASE64Encoder;import java.io.UnsupportedEncodingException; import java.net.URLEncoder;/*** 處理下載文件的中文名無法顯示的問題** @author liaowenxiong* @date 2022/1/13 11:55*/public class DownloadUtils {public static String getFileName(String agent, String filename) throws UnsupportedEncodingException, UnsupportedEncodingException {if (agent.contains("М?IЕ")) {// 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;} }最終完整的文件下載的示例代碼:
package priv.lwx.javaex.servlet_demo.web.servlet.download; /*** 文件下載的示例代碼** @author liaowenxiong* @date 2022/1/12 21:57*/import priv.lwx.javaex.servlet_demo.util.DownloadUtils;import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException;@WebServlet("/download") public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.獲取請求參數fileNameString fileName = request.getParameter("fileName");// 2.使用字節輸入流加載文件進內存// 2.1.獲取文件的服務器路徑String realPath = this.getServletContext().getRealPath("/image/" + fileName);// 2.2.獲取文件的文件字節輸入流(用文件字節流關聯文件)FileInputStream fis = new FileInputStream(realPath); // 這步就完成了讀取文件數據進內存的操作// System.out.println(fis);// 3.設置響應頭// 3.1.設置響應頭content-typeServletContext context = this.getServletContext();// 獲取文件的MIME類型String mimeType = context.getMimeType(fileName);// 告訴客戶端響應體的數據類型response.setHeader("content-type", mimeType);// 3.2.設置響應頭content-disposition// 獲取請求頭user-agent/* String agent = request.getHeader("user-agent");// 根據瀏覽器版本對文件名進行不同的處理,以解決中文無法顯示的問題fileName = DownloadUtils.getFileName(agent, fileName);*/response.setHeader("content-disposition", "attachement;filename=" + fileName);// filename是在下載提示框顯示的文件名// 4.將輸入流的數據寫入到輸出流中(類似文件復制的操作)// 4.1.獲取字節輸出流ServletOutputStream sos = response.getOutputStream();// 4.2.定義讀取到的字節數據的緩沖區byte[] buff = new byte[1024 * 8];int len = 0;// 將字節數據讀取到字節數組中,返回讀取到的字節數,如果返回的字節數不是-1,說明沒有讀到文件末尾// 注意:字節輸入流每次讀取到字節數組中的數據會覆蓋原來的舊數據while ((len = fis.read(buff)) != -1) {// 將字節數組中的字節數據寫入到字節輸出流中,sos.write(buff, 0, len);}// 5.釋放資源fis.close();} }總結
以上是生活随笔為你收集整理的Java文件下载/下载文件的案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 索尼电脑检测不到电池(索尼手机检测电池)
- 下一篇: 电脑上怎样安装声卡驱动(电脑怎么安装驱动