基礎思路:
之前的思路一直是彈出一個框問使用者想要存放檔案的位置,然後我再產生個檔案放到那。然而我這個想法並沒有成功。
點選連結來下載檔案的方式很簡便,後台把檔案流輸出來,通過瀏覽器實現下載功能,包括詢問位置與檔案存放,大多數瀏覽器會配置一個固定位置,不一定每次都問。
前端就非常簡單了,一個<a>標籤,href=“後台方法地址”,如果你的需求不能直接用超連結方式,可以在js裡寫
window.location.href =“後台方法地址"。
這樣跳轉到後台方法後
String filePath = this.getClass().getClassLoader().getResource("").toURI().getPath() + "/exportPdf.pdf"; //檔案在項目中的路徑 File outfile = new File(filePath); String filename = outfile.getName();// 擷取檔案名稱 InputStream fis = new BufferedInputStream(new FileInputStream( filePath)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); //讀取檔案流 fis.close(); response.reset(); //重設結果集 response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.replaceAll(" ", "").getBytes("utf-8"), "iso8859-1")); //返回頭 檔案名稱 response.addHeader("Content-Length", "" + outfile.length()); //返回頭 檔案大小 response.setContentType("application/octet-stream"); //設定資料種類 //擷取返回體輸出權 OutputStream os = new BufferedOutputStream(response.getOutputStream()); os.write(buffer); // 輸出檔案 os.flush(); os.close();
瀏覽器會直接識別這種形式的檔案輸出,彈出對話方塊。
注意此方法一定要用連結方式調後台,使用ajax和XMLHttpRequest方式都是不行的,這樣返回的檔案流會返回到方法的回呼函數中,當然如果你想在js中擷取檔案,這樣也行。
執行個體
package cn.itcast.day06.web.servlet; import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URLEncoder; import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; public class DownloadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 實現防盜鏈功能 // 獲得 referer 頭 用於說明來訪者來自哪裡 String referer = request.getHeader("referer"); if(referer==null || !referer.startsWith("http://localhost")) { // 是盜鏈者 response.sendRedirect("/day06/index.jsp"); return ; } // 解決response中文亂碼問題 response.setContentType("text/html;charset=utf-8"); // 設定訊息體的編碼 // 通過 http 協議 發送的http響應訊息頭 不能出現中文 中文必須要經過url編碼 String filename = URLEncoder.encode("美女.jpg", "utf-8"); // 通知瀏覽器以下載的方式讀取資源 response.setHeader("content-disposition", "attachment;filename="+filename); // 讀取圖片資料 發給ie瀏覽器 String webPath = "/download/美女.jpg"; // 相當於當前web應用的path ServletContext servletContext = super.getServletContext(); InputStream in = servletContext.getResourceAsStream(webPath); OutputStream out = response.getOutputStream(); int len; byte[] buffer = new byte[1024]; while((len=in.read(buffer))!=-1) out.write(buffer, 0, len); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }