response介紹及應用、亂碼問題解決
1. http協議響應資料-response
1.1. 響應資料組成
1.2. 響應行
HTTP/1.1 200 OK |
格式:協議版本+http狀態碼+狀態碼含義
1.2.1. http狀態碼
介紹
用於描述使用者瀏覽器與伺服器通訊過程中的狀態表示
狀態碼個數
常用狀態碼
200,通訊正常
304,通知瀏覽器使用快取(瀏覽器本地有快取檔案,不請求伺服器了)
404,伺服器上沒有找到對應的資源。使用者的錯誤,使用者輸錯了url導致的。
405,提交的請求方式伺服器上沒有相應的方法處理,比如,使用者提交了post請求,servlet裡面沒有doPost()方法就會報錯.
500,伺服器發生錯誤了,錯誤是由開發人員程式碼邏輯不完全導致的。99%是開發人員的錯誤。
302,通知瀏覽器進行頁面跳轉的動作執行
1.3. 響應頭
1.3.1. 請求頭介紹
響應頭的資料構成,響應頭的資料是響應給瀏覽器,一般我們不用讀取,但是我們可以設定響應頭的資料,讓瀏覽器按照我們指定的設定進行執行響應的功能。響應頭資訊如下:
Location:http://www.it315.org/index.jsp --跳轉方向
Server:apache tomcat --伺服器型號
Content-Encoding:gzip --資料壓縮
Content-Length: 80 --資料長度
Content-Language: zh-cn --語言環境
Content-Type:text/html; charset=GB2312 --編碼
Last-Modified: Tue, 11 Jul2000 18:23:51 GMT --最後修改時間
Refresh:1;url=http://www.it315.org --定時重新整理
Content-Disposition:attachment; filename=aaa.zip --下載
Set-Cookie:SS=Q0=5Lb_nQ;path=/search
Expires: -1
Cache-Control: no-cache --快取
Pragma: no-cache --快取
Connection:close/Keep-Alive --連線
Date: Tue, 11 Jul 200018:23:51 GMT --時間
1.3.2. 設定響應頭的核心方法
response.setHeader(name,value) | 由於響應頭的格式是以key-value的格式,所以設定響應頭的資料需要設定這兩個引數就可以了 |
例子
response.setHeader(“location”,”/day37/hello.html”); |
1.3.3. Location
1.3.3.1. 作用
響應頭location的作用是通知瀏覽器要進行頁面跳轉的目標地址。
http狀態碼302的作用是通知瀏覽器進行頁面跳轉的動作執行,所以響應頭location
和http狀態碼302配合起來才可以完成頁面跳轉。
1.3.3.2. 實現跳轉程式碼
//需求:跳轉到資源CountServlet
//response.setHeader(name, value); 設定響應頭key-value格式
response.setHeader("location", "/day37/count");
//設定http狀態碼為302
response.setStatus(302);
1.3.3.3. 優化跳轉資原始碼
//一句搞定頁面跳轉,實現原理就是上面的2句程式碼
//day37不能寫死在程式碼中,防止修改工程名字,建議使用servletContext獲取工程名字
response.sendRedirect(getServletContext().getContextPath()+"/count");
1.3.4. Content-Encoding
1.3.4.1. 格式
Content-Encoding:gzip --資料壓縮響應頭資訊
1.3.4.2. 作用
通知瀏覽器解壓資料後再顯示資料。Content-Encoding:gzip,瀏覽器只支援解壓gzip格式的壓縮檔案。
1.3.4.3. 介紹
一般向客戶端瀏覽器輸出大量資料時,為了提供網路傳輸資料需要對資料進行壓縮之後在響應給瀏覽器,但是瀏覽器接收的是一個壓縮檔案,所以需要伺服器設定響應頭content-encoding通知瀏覽器解壓檔案後再顯示資料。
1.3.5. Content-Type
1.3.5.1. 格式
Content-Type:text/html; charset=GB2312 --編碼
1.3.5.2. 介紹
官方叫法,設定響應正文型別,報文型別,一共包含2部分內容。
第一部分text/htm設定響應的資料型別Mime-Type,這裡設定的是響應文字字串html程式碼。伺服器可以響應任何型別的資源給客戶端,資源不同,Mime-Type不同。
這裡設定的是響應文字字串html程式碼。伺服器可以響應任何型別的資源給客戶端,資源不同,Mime-Type不同。例如
text/html | Html程式碼 |
text/plain | Txt文字檔案 |
image/jpeg | Jpg圖片檔案 |
Application/json | Json資料 |
第二部分charset=GB2312,響應的字元碼錶gb2312
通知瀏覽器以什麼碼錶解碼資料
1.3.5.3. 作用
content-type用於伺服器通知瀏覽器採用什麼碼錶對伺服器響應的資料進行解碼。由於伺服器響應資料預設採用iso8859-1碼錶,然而中國大陸瀏覽器預設採用GBK碼錶,所以通過設定響應頭content-type來統一碼錶,解決響應中文資料亂碼問題。
1.3.5.4. 伺服器端輸出中文資料有2種方式
1.3.5.4.1. 位元組流輸出
response.getOutputStream().write("你好".getBytes());
1.3.5.4.2. 字元流輸出
//輸出的字元流
PrintWriterout = response.getWriter();
//輸出字元
out.write("你好");//會亂碼
1.3.5.5. 解決伺服器輸出字元流中文亂碼
1.3.5.5.1. 亂碼介紹
瀏覽器與伺服器傳輸中文資料會亂碼,原因就是伺服器響應資料預設採用iso8859-1碼錶,瀏覽器預設採用GBK碼錶,所以就會亂碼
1.3.5.5.2. 解決伺服器輸出字元流中文亂碼問題實現原理
說明:瀏覽器與伺服器傳輸中文資料需要進行url編碼,url編碼過程如下:
1. 對位元組陣列中的負數加256
2. 將加後的位元組陣列轉換為十六進位制整型資料
3. 之後在每個16進位制資料前加%
例如瀏覽器與伺服器傳輸你好兩個漢字,真實傳遞的是url編碼資料“%E3%BK%A1%B6%19%BA”,如下圖就是模擬伺服器輸出你好給瀏覽器最終顯示結果“??”亂碼了的過程
解決上圖輸出中文字元流亂碼問題需要2個步驟:
1. 伺服器預設輸出中文編碼iso8859-1碼錶修改為utf-8編碼碼錶
2. 伺服器通知瀏覽器採用utf-8解碼碼錶解析資料
1.3.5.5.3. 使用響應頭content-type解決亂碼程式碼
//優化解決中文亂碼程式碼
//(即實現修改伺服器編碼碼錶為utf-8,又實現通知瀏覽器解碼碼錶utf-8)
//實現原理是封裝了上面2句程式碼
response.setContentType("text/html;charset=utf-8");
//輸出的字元流
PrintWriter out = response.getWriter();
//輸出字元
1.3.5.5.4. 優化解決亂碼程式碼
//優化解決中文亂碼程式碼
//(即實現修改伺服器編碼碼錶為utf-8,又實現通知瀏覽器解碼碼錶utf-8)
//實現原理是封裝了上面2句程式碼
response.setContentType("text/html;charset=utf-8");
//輸出的字元流
PrintWriter out = response.getWriter();
//輸出字元
out.write("hello world 你好");
思考問題 publicvoid doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getOutputStream().write("你好".getBytes()); //思考,字元流輸出中文預設亂碼,位元組流輸出預設不亂碼,為什麼呢? //.getBytes()如果無參,預設是GBK編碼,瀏覽器有預設以gbk解碼,所以不亂碼了 //使用位元組流不安全,因為只有中國瀏覽器預設以GBK解碼。 //所以,輸出中文,建議字元流,明確設定伺服器碼錶與瀏覽器碼錶一樣就安全了 } |
1.3.1. refresh
1.3.1.1. 格式
Refresh:1;url=http://www.it315.org --定時重新整理
描述:1秒以後頁面跳轉到http://www.it315.org
1.3.1.2. 作用
設定瀏覽器定時重新整理頁面或定時跳轉到指定的資源
1.3.2. Content-Disposition
1.3.2.1. 格式
Content-disposition :attachment; filename=aaa.zip --下載
attachment,通知瀏覽器不要顯示資料要以附件形式下載
filename=aaa.zip,下載的檔名字
1.3.2.2. 作用
通知瀏覽器不要直接顯示資料,以附件形式下載資料。預設瀏覽器檢視資料是直接顯示資料,有的資源下載網站需要下載資源資料而不是直接顯示,所以需要通過設定響應頭content-disposition來通知瀏覽器以附件下載資料。
1.3.2.3. 案例:實現不同型別的檔案下載
l 使用超連結下載的不足:
1) 文字和圖片是直接開啟,不是下載
2) 容易暴露真實地址,有可能會有盜鏈
l 步驟:
1) 從連結上得到檔名
2) 得到檔案的MIME型別
3) 設定content-type頭為MIME型別
4) 設定content-disposition頭
5) 得到檔案的輸入流
6) 得到response的輸出流
7) 寫出到瀏覽器端
8) 下載檔名使用漢字的情況
l 下載頁面:
<!DOCTYPE html>
<html>
<head>
<title>資源下載列表</title>
<meta charset="utf-8">
</head>
<body>
<h2>檔案下載頁面列表</h2>
<h3>超連結的下載</h3>
<a href="download/file.txt">文字檔案</a><br/>
<a href="download/file.jpg">圖片檔案</a><br/>
<a href="download/file.zip">壓縮檔案</a><br/>
<hr/>
<h3>手動編碼的下載方式</h3>
<a href="down?filename=file.txt">文字檔案</a><br/>
<a href="down?filename=file.jpg">圖片檔案</a><br/>
<a href="down?filename=file.zip">壓縮檔案</a><br/>
</body>
</html>
DownServlet
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //處理手動編碼下載請求 // 1) 從連結上得到檔名 String file = request.getParameter("filename"); // 2) 得到檔案的MIME型別 System.out.println(type); // 3) 設定content-type頭為MIME型別 response.setHeader("content-type", type); // 4) 設定content-disposition頭,以附件的方式下載檔案filename後是檔名,在ie和chrome中漢字使用url編碼格式 // 5) 得到檔案的輸入流 InputStream in = getServletContext().getResourceAsStream("/download/" + file); // 6) 得到response的輸出流 OutputStream out = response.getOutputStream(); // 7) 寫出到瀏覽器端 int len = 0; byte[] buf = new byte[1024]; out.write(buf,0,len); } in.close(); out.close(); } |
1.4. 響應體
1.4.1. 介紹
就是伺服器輸出資料給使用者看,瀏覽器直接要顯示給使用者,就是伺服器輸出資料
1.4.2. 作用
1. 輸出字元資料、位元組資料
2. 輸出資原始檔資料(資源圖片)
3. 輸出快取(記憶體中)圖片(資源沒有對應的物理資源)--驗證碼