[轉]【HttpServlet】HttpServletResponse接口 案例:完成文件下載


創建時間:6.19 & 6.24

 

1.案例-完成文件下載

 

1)  什么情況下會文件下載?

瀏覽器不能解析的文件就下載

 

*使用a標簽直接指向服務器上的資源

 

 

2)什么情況下需要在服務端編寫文件下載的代碼?

理論上,瀏覽器可以解析的代碼需要編寫文件下載代碼

實際開發中,只要是下載的文件都編寫文件下載代碼

 

 

文件下載的實質就是文件拷貝,將文件從服務器端拷貝到瀏覽器端。所以文件下載需要IO技術將服務器端的文件使用InputStream讀取到,在使用      ServletOutputStream寫到response緩沖區中

 

代碼如下:

 

上述代碼可以將圖片從服務器端傳輸到瀏覽器,但瀏覽器直接解析圖片顯示在頁面上,而不是提供下載,我們需要設置兩個響應頭,告知瀏覽器文件的類型和文件的打開方式。

1)告知瀏覽器文件的類型:response.setContentType(文件的MIME類型);

2)告示瀏覽器文件的打開方式是下載:

response.setHeader("Content-Disposition","attachment;filename=文件名稱");

 

代碼如下:

 

*客戶端不是根據文件擴展名來區分文件的類型,而是通過文件的MIME類型(在tomcat的web.xml中對extension進行MIME的映射)

 

但是,如果下載中文文件,頁面在下載時會出現中文亂碼或不能顯示文件名的情況,  原因是不同的瀏覽器默認對下載文件的編碼方式不同,ie是UTF-8編碼方式,而火狐瀏覽器是Base64編碼方式。所里這里需要解決瀏覽器兼容性問題,解決瀏覽器兼容   性問題的首要任務是要辨別訪問者是ie還是火狐(其他),通過Http請求體中的一個屬性可以辨別

 

解決亂碼方法如下(不要記憶--了解):

 

 其中agent就是請求頭User-Agent的值

 1 if (agent.contains("MSIE")) {
 2 
 3             // IE瀏覽器
 4 
 5             filename = URLEncoder.encode(filename, "utf-8");
 6 
 7             filename = filename.replace("+", " ");
 8 
 9 } else if (agent.contains("Firefox")) {
10 
11             // 火狐瀏覽器
12 
13 BASE64Encoder base64Encoder = new BASE64Encoder();
14 
15             filename = "=?utf-8?B?"
16 
17                       + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
18 
19 } else {
20 
21             // 其它瀏覽器
22 
23             filename = URLEncoder.encode(filename, "utf-8");                    
24 
25 }

 

 

完整代碼:見WEB14代碼DownloadServlet2.java

 

  1 package com.itheima.content;
  2 
  3  
  4 
  5 import java.io.FileInputStream;
  6 
  7 import java.io.IOException;
  8 
  9 import java.io.InputStream;
 10 
 11 import java.net.URLEncoder;
 12 
 13  
 14 
 15 import javax.servlet.ServletException;
 16 
 17 import javax.servlet.ServletOutputStream;
 18 
 19 import javax.servlet.http.HttpServlet;
 20 
 21 import javax.servlet.http.HttpServletRequest;
 22 
 23 import javax.servlet.http.HttpServletResponse;
 24 
 25  
 26 
 27 import sun.misc.BASE64Encoder;
 28 
 29  
 30 
 31 public class DownLoadServlet2 extends HttpServlet {
 32 
 33  
 34 
 35       protected void doGet(HttpServletRequest request, HttpServletResponse response)
 36 
 37                   throws ServletException, IOException {
 38 
 39  
 40 
 41             //*******文件名稱是中文的下載*******
 42 
 43  
 44 
 45  
 46 
 47             //獲得要下載的文件的名稱
 48 
 49             String filename = request.getParameter("filename");//????.jpg
 50 
 51             //解決獲得中文參數的亂碼----下節課講
 52 
 53             filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg
 54 
 55  
 56 
 57            
 58 
 59             //獲得請求頭中的User-Agent
 60 
 61             String agent = request.getHeader("User-Agent");
 62 
 63             //根據不同瀏覽器進行不同的編碼
 64 
 65             String filenameEncoder = "";
 66 
 67             if (agent.contains("MSIE")) {
 68 
 69                   // IE瀏覽器
 70 
 71                   filenameEncoder = URLEncoder.encode(filename, "utf-8");
 72 
 73                   filenameEncoder = filenameEncoder.replace("+", " ");
 74 
 75             } else if (agent.contains("Firefox")) {
 76 
 77                   // 火狐瀏覽器
 78 
 79                   BASE64Encoder base64Encoder = new BASE64Encoder();
 80 
 81                   filenameEncoder = "=?utf-8?B?"
 82 
 83                              + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
 84 
 85             } else {
 86 
 87                   // 其它瀏覽器
 88 
 89                   filenameEncoder = URLEncoder.encode(filename, "utf-8");                  
 90 
 91             }
 92 
 93  
 94 
 95  
 96 
 97  
 98 
 99             //要下載的這個文件的類型-----客戶端通過文件的MIME類型去區分類型
100 
101             response.setContentType(this.getServletContext().getMimeType(filename));
102 
103             //告訴客戶端該文件不是直接解析 而是以附件形式打開(下載)----filename="+filename 客戶端默認對名字進行解碼
104 
105             response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
106 
107  
108 
109             //獲取文件的絕對路徑
110 
111             String path = this.getServletContext().getRealPath("download/"+filename);
112 
113             //獲得該文件的輸入流
114 
115             InputStream in = new FileInputStream(path);
116 
117             //獲得輸出流---通過response獲得的輸出流 用於向客戶端寫內容
118 
119             ServletOutputStream out = response.getOutputStream();
120 
121             //文件拷貝的模板代碼
122 
123             int len = 0;
124 
125             byte[] buffer = new byte[1024];
126 
127             while((len=in.read(buffer))>0){
128 
129                   out.write(buffer, 0, len);
130 
131             }
132 
133  
134 
135             in.close();
136 
137             //out.close();
138 
139  
140 
141       }
142 
143  
144 
145       protected void doPost(HttpServletRequest request, HttpServletResponse response)
146 
147                   throws ServletException, IOException {
148 
149             doGet(request, response);
150 
151       }
152 
153 }

 

 

response細節點:

1)response獲得的流不需要手動關閉,web容器(tomcat)會幫助我們關閉

2)getWritergetOutputStream不能同時調用

 

 

 

驗證碼案例:不用掌握生成驗證碼,只要掌握html頁面里怎么改


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM