1. 程式人生 > >response介紹及應用、亂碼問題解決

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後是檔名,在iechrome中漢字使用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.      輸出快取(記憶體中)圖片(資源沒有對應的物理資源)--驗證碼