一、HttpServletResponse的概述
web服務器收到客戶端的http請求,會針對每一次請求,分別創建一個用於代表請求的request對象、和代表響應的response對象。
request和response對象即代表請求和響應。我們要獲取客戶機提交的數據,只需要找request對象就行了;要向客戶機發送數據,只需要找response對象就行了。
二、HttpServletResponse的運行流程
三、Http響應
四、通過response設置響應行
// 設置狀態碼,302重定向
response.setStatus(302);
五、設置response響應頭
// 添加響應頭
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
// 設置響應頭
setHeader(String name, String value)
setIntHeader(String name, int value)
setDateHeader(String name, long date)
【注意】add方法會有多個值,但是set方法只有最有一個值
重定向:
狀態碼:302 響應頭:location代表重定向的地址
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
response.setCharacterEncoding("UTF-8");
String str1 = "王思偉,我愛你!!!";
String str2 = new String(str1.getBytes("iso8859-1"),"UTF-8");
response.getWriter().write(str2);;
}
六、通過response設置響應體
(1)響應體設置文本
獲得字符流,通過字符流的write(
String s)
方法可以將字符串設置到response 緩衝區中,隨後Tomcat會將response緩衝區中的內容組裝成Http響應返回給瀏覽 器端。
關於設置中文的亂碼問題
原因:response緩衝區的默認編碼是iso8859-1,此碼錶中沒有中文,可以通過 response的setCharacterEncoding(
String charset)
設置response的編碼
但我們發現客戶端還是不能正常顯示文字
原因:我們將response緩衝區的編碼設置成UTF-8,但瀏覽器的默認編碼是本地系 統的編碼,因爲我們都是中文系統,所以客戶端瀏覽器的默認編碼是GBK,我們可以 手動修改瀏覽器的編碼是UTF-8。
我們還可以在代碼中指定瀏覽器解析頁面的編碼方式,
通過response的setContentType(
String type)
方法指定頁面解析時的編碼是UTF-8
response.setContentType("text/html;charset=UTF-8");
上面的代碼不僅可以指定瀏覽器解析頁面時的編碼,同時也內含 setCharacterEncoding的功能,所以在實際開發中只要編寫 response.setContentType("text/html;charset=UTF-8");就可以解決頁面輸出中文亂碼問題。
response編碼和解碼的過程分析示意圖:
(2)響應頭設置字節
ServletOutputStream
getOutputStream()
獲得字節流,通過該字節流的write(byte[] bytes)可以向response緩衝區中寫入字 節,在由Tomcat服務器將字節內容組成Http響應返回給瀏覽器。
7、案例-完成文件下載
文件下載的實質就是文件拷貝,將文件從服務器端拷貝到瀏覽器端。所以文件下載需 要IO技術將服務器端的文件使用InputStream讀取到,在使用 ServletOutputStream寫到response緩衝區中
問題:
1)什麼情況下回文件下載?
瀏覽器不能解析的文件就下載
2)什麼情況下需要在服務器端編寫文件下載的代碼?
理論上,瀏覽器可以解析的文件需要編寫文件下載代碼
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// *******文件名稱是中文的下載*******
// 獲得要下載的文件的名稱
String filename = request.getParameter("filename");// 美女.jpg
System.out.println(filename);
// 解決獲得中文參數的亂碼----下節課講
//filename = new String(filename.getBytes("ISO8859-1"), "UTF-8");// ????.jpg
System.out.println(filename);
// 獲得請求頭中的User-Agent
String agent = request.getHeader("User-Agent");
// 根據不同瀏覽器進行不同的編碼
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE瀏覽器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
// 要下載的這個文件的類型-----客戶端通過文件的MIME類型去區分類型
response.setContentType(this.getServletContext().getMimeType(filename));
// 告訴客戶端該文件不是直接解析 而是以附件形式打開(下載)----filename="+filename 客戶端默認對名字進行解碼
response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder);
// 這兒的filenameEncoder是對"美女.jpg"進行鍼對不同瀏覽器進行的編碼,
// 不再是"美女.jpg",因爲它不識別(導致下載的文件沒名稱)
// 獲取文件的絕對路徑
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();out.close()可不必寫
}
上述代碼可以將圖片從服務器端傳輸到瀏覽器,但瀏覽器直接解析圖片顯示在頁面上, 而不是提供下載,我們需要設置兩個響應頭,告知瀏覽器文件的類型和文件的打開方 式。
- 告知瀏覽器文件的類型:response.setContentType(文件的MIME類型);
- 告示瀏覽器文件的打開方式是下載:
response.setHeader("Content-Disposition","attachment;filename=文件名稱");
但是,如果下載中文文件,頁面在下載時會出現中文亂碼或不能顯示文件名的情況, 原因是不同的瀏覽器默認對下載文件的編碼方式不同,ie是UTF-8編碼方式,而火狐 瀏覽器是Base64編碼方式。所裏這裏需要解決瀏覽器兼容性問題,解決瀏覽器兼容 性問題的首要任務是要辨別訪問者是ie還是火狐(其他),通過Http請求體中的一 個屬性可以辨別
解決亂碼方法如下(不要記憶--瞭解):
if (agent.contains("MSIE")) {
// 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");
}
response細節點:
1)response獲得的流不需要手動關閉,Tomcat容器會自動關閉
2)getWriter()和getOutputStream不能同時使用