JAVA檔案下載
阿新 • • 發佈:2018-12-10
1.首先在html頁面使用a標籤來連線到需要下載的資源,資源是放在WebContent下的download目錄下的
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h2>使用伺服器端編碼的方式實現檔案下載</h2> <a href="/WEB14/downloadServlet?fileName=a.flv">點選下載a.flv視訊</a><br/> <a href="/WEB14/downloadServlet?fileName=b.jpg">點選下載b.jpg圖片</a><br/> <a href="/WEB14/downloadServlet?fileName=c.mp3">點選下載c.mp3音訊</a><br/> </body> </html>
2.在DownloadServlet中告訴客戶端檔案不用解析直接下載
package com.content; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; 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; @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得要下載的檔案的名稱 String fileName = request.getParameter("fileName"); //要下載的檔案的型別----客戶端通過檔案的MIME型別來區別檔案型別(這個可以不用寫) //response.setContentType(this.getServletContext().getMimeType(fileName)); //告訴客戶端該檔案不是直接解析,而是下載(後面拼上檔案的名字) response.setHeader("Content-Disposition","attachment;filename="+fileName); //獲取檔案的絕對路徑 String path = this.getServletContext().getRealPath("download/"+fileName); //獲得該檔案的輸入流 InputStream in = new FileInputStream(path); //獲得輸出流---通過response獲得的輸出流,用於向客戶端寫內容 ServletOutputStream out = response.getOutputStream(); //檔案拷貝(檔案下載其實就是檔案拷貝) int len = 0; byte[] buffer = new byte[1024]; while((len=in.read(buffer))>0) { out.write(buffer,0,len); } in.close(); out.close();//這個可以不寫,因為是由response建立的輸出流物件,tomcat容器會幫我們關上 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3.上面的DownloadServlet無法下載中文名的檔案,需要優化編碼
package com.content; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; 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 sun.misc.BASE64Encoder; @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得要下載的檔案的名稱,這裡獲得的要是中文檔名會產生亂碼,需要處理 String fileName = request.getParameter("fileName"); //解決中文亂碼問題,但是後續編碼依舊會有問題 fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8"); //要下載的檔案的型別----客戶端通過檔案的MIME型別來區別檔案型別(這個可以不用寫) //response.setContentType(this.getServletContext().getMimeType(fileName)); //獲得請求頭中的User-Agent,這段程式碼不許要記憶,要用時直接拿來用就行了 String agent = request.getHeader("User-Agent"); String chineseFileName = ""; //根據不同瀏覽器進行不同的編碼 if(agent.contains("MSIE")) { //IE瀏覽器 chineseFileName = URLEncoder.encode(fileName, "utf-8"); chineseFileName = chineseFileName.replace("+", " "); }else if(agent.contains("Firefox")) { //火狐瀏覽器 BASE64Encoder base64Encoder = new BASE64Encoder(); chineseFileName = "=?utf-8?B?"+base64Encoder.encode(fileName.getBytes("utf-8"))+"?="; }else { chineseFileName = URLEncoder.encode(fileName, "utf-8"); } //告訴客戶端該檔案不是直接解析,而是下載(後面拼上檔案的名字),這裡的fileName客戶端用預設的編碼解析,所以我們需要用對應客戶端的解碼形式來進行編碼 response.setHeader("Content-Disposition","attachment;filename="+chineseFileName); //獲取檔案的絕對路徑 String path = this.getServletContext().getRealPath("download/"+fileName); //獲得該檔案的輸入流 InputStream in = new FileInputStream(path); //獲得輸出流---通過response獲得的輸出流,用於向客戶端寫內容 ServletOutputStream out = response.getOutputStream(); //檔案拷貝(檔案下載其實就是檔案拷貝) int len = 0; byte[] buffer = new byte[1024]; while((len=in.read(buffer))>0) { out.write(buffer,0,len); } in.close(); out.close();//這個可以不寫,因為是由response建立的輸出流物件,web容器會幫我們關上 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }