基礎思路:
之前的思路一直是彈出一個框問用戶想要存放文件的位置,然后我再生成個文件放到那。然而我這個想法并沒有成功。
點擊鏈接來下載文件的方式很簡便,后臺把文件流輸出來,通過瀏覽器實現下載功能,包括詢問位置與文件存放,大多數瀏覽器會配置一個固定位置,不一定每次都問。
前端就非常簡單了,一個<a>標簽,href=“后臺方法地址”,如果你的需求不能直接用超鏈接方式,可以在js里寫
1
|
window.location.href =“后臺方法地址"。 |
這樣跳轉到后臺方法后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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中獲取文件,這樣也行。
實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
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); } } |