1. 程式人生 > >response亂碼的問題及setCharacterEncoding()與setContentType()區別

response亂碼的問題及setCharacterEncoding()與setContentType()區別

這裡我們輸出的是"Hello World"英文,使用瀏覽器去訪問的時候是沒有亂碼問題,下面我們在將程式碼改寫一下,

  1. response.getOutputStream.write("中國".getBytes("utf-8"));  
這時候我們使用瀏覽器去訪問資料的時候,當然我們可能會看到"中國",也有可能看到的是亂碼,原因很簡單,如果瀏覽器使用的是gb2312碼錶開啟的話,就是亂碼,如果是使用utf-8碼錶開啟的話,就是正常的資料。當然我們可以手動的去設定瀏覽器的開啟碼錶,預設的是gb2312(系統預設碼錶),那麼如果我們使用utf-8將資料寫入到Response中,然後瀏覽器使用的是預設的碼錶去拿取資料進行顯示,那肯定是亂碼了,那麼我們該怎麼辦呢?,讓使用者手動的去修改瀏覽器的開啟碼錶,那貌似太噁心了,所以這裡我們就要介紹一個響應頭欄位的作用了,Content-type:這個頭就是告訴瀏覽器以什麼方式開啟資料,並且指定相應的碼錶,具體程式碼如下:
  1. response.setHeader("Content-type""text/html;charset=utf-8");  
這樣,我們就可以告訴瀏覽器以utf-8碼錶去顯示資料,這樣也就不會再有亂碼的問題了。

這裡我們在擴充套件一下就是還有一種方式控制瀏覽器的開啟碼錶,那就是使用<meta>標籤來實現:

  1. response.getOutputStream().write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());  
這裡我們組建了一個<meta>標籤,並將這個標籤寫入到Response容器中,當客戶機使用去拿取這段資料的時候,發現有html中的標籤<meta>所以會通過一些處理會把上面的字串當做是是html程式碼來顯示。這裡使用了<meat>標籤來解決亂碼問題的。

上面使用的是位元組流的方式來給客戶機發送資料的,有時候我們可能會使用字元流來顯示資料,因為字元流在特定場合下回比位元組流更方便的輸出,其實這裡使用response.getWriter()來獲取一個PrintWriter字元流物件,然後我們可以使用PrintWriter物件的write方法直接寫字串資料,但是這裡也是需要來解決亂碼的問題,而且這裡的需要解決的問題比上面的位元組流更麻煩。下面來看一下吧:

  1. response.getWriter.write("中國");  
通過上面的方法進行輸出,顯示的是亂碼,首先servlet將"中國"字串寫入到Response容器中,但是這裡需要注意的一個問題就是,將"中國"寫入到Response中,那麼Response容器中是怎麼儲存"中國"字串的,因為Response這些技術都是老外發明的,所以他們肯定是使用iso8859-1編碼來進行儲存位元組資料的,所以這裡就會有一個大問題,因為我們知道iso8859-1使用的是單個位元組表示一個字元的,而gb2312使用的是兩個位元組,utf-8使用的是三個位元組,所以Response將使用iso8859-1碼錶進行編碼,那麼儲存的是兩個亂碼位元組,所以,當客戶機從Response容器中去拿取資料的時候顯示的肯定是亂碼,那麼當我們使用
  1. response.setHeader("Content-type","text/html;charset=utf-8")  
來設定瀏覽器的開啟資料的碼錶,但是我們會發現還是顯示兩個??,這個也是很簡單的,因為我們在編寫JavaSE中,也會知道這個問題就是將utf-8這種多位元組的碼錶轉到低位元組碼錶iso8859-1,當我這時候在將結果轉成utf-8的資料,這時候是不可能在轉回原始資料的。所以說我們應該去修改Response容器的碼錶,將其碼錶改成utf-8,這時候就可以"中國"寫入到Response容器中,而且會以utf-8的碼錶進行儲存的,當客戶機在用utf-8碼錶開啟的時候就不會有問題了,

上面我們使用位元組流來進行書寫資料的時候,是沒有問題的,因為是將"中國"的位元組資料直接寫到Response容器中的,所以不會涉及到Response容器編碼的問題。

所以說當我們在使用字元流寫入資料的時候,我們一定要記得修改Response容器的編碼,不然會出現亂碼的

  1. response.setCharacterEncoding("utf-8");  
  2. response.setHeader("content-type""text/html;charset=utf-8");  
所以要用這兩行程式碼的,同時response物件中還有一個方法:setContentType,這個方法可以直接設定Content-type欄位的值
  1. response.setContentType("text/html;charset=utf-8");  

其實這一行程式碼就相當於上面的兩行程式碼的效果,因為在setContentType方法中已經呼叫了setCharacterEncoding方法設定了Response容器的編碼了。

原文地址:http://blog.csdn.net/jiangwei0910410003/article/details/22886847