文章目錄
- 字元編碼
- get請求亂碼
- post請求亂碼
- 響應亂碼
字元編碼
- 了解:字元與計算機底層二進制資料的對應關系的表。
-
各個編碼集之間的關系:
ASCII:美國标準資訊交換碼。用一個位元組的7位可以表示。
ISO8859-1:拉丁碼表。用一個位元組的8位表示。
GB2312:中國的中文編碼表。最多兩個位元組編碼所有字元。
GBK:中國的中文編碼表更新。最多兩個位元組編碼。
Unicode:國際标準碼。所有的文字都用兩個位元組來表示。
UTF-8:變長的編碼方式。可用1-4個位元組來表示一個字元。
演變:①最早使用ASCII,但是隻有字母。②ISO8859-1、GB2312、GBK統稱為ANSI編碼,通常指的是平台的預設編碼,例如英文作業系統中是ISO-8859-1,中文系統是GBK;解碼時可用二進制首位是1還是0來确定,兩個位元組還是一個位元組表示一個字元。③Unicode融合了所有國家字元的編碼,但是解碼時無法确定幾個位元組表示一個字元,這時候引入了編碼方式,UTF-8,UTF-16輸入編碼方式,這時候編碼表和編碼方式就分開了。
- 這裡我們隻需要知道幾點:
- 字元–>二進制:編碼。二進制–>字元:解碼。
- 資料是以二進制的方式進行傳輸的。
- Unicode是編碼集,UTF-8是基于Unicode編碼集的編碼方式。
get請求亂碼
- 現象:get請求送出中文,此時中文參數拼接在url中
-
原因:伺服器解析url時不知道編碼規則
浏覽器送出請求時,url是按照utf-8方式進行編碼的;伺服器在解析url時,進行解碼時沒有使用utf-8方式解碼,而是使用伺服器預設方式解碼,編碼方式和解碼方式不同,是以出現亂碼。
-
解決:修改伺服器配置檔案:server.xml。找到<Connector>标簽添加URIEncoding="utf-8"屬性。
解析url時,是在攔截8080端口請求時,還沒有到封裝請求資料到request那一步,是以改代碼沒有用,要改tomcat端口配置。
post請求亂碼
- 現象:post請求送出中文,此時中文參數放在請求體中
-
原因:伺服器解析請求體中的參數時不知道編碼規則
浏覽器送出請求時,是按照utf-8方式進行編碼的;伺服器解析請求體中資料時,進行解碼時沒有使用 utf-8方式解碼,而是使用伺服器預設方式解碼,編碼方式和解碼方式不同,是以出現亂碼。
- 解決:request.setCharacterEncoding(“utf-8”);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println(username);
}
響應亂碼
- 現象:response.getWriter.write(“中文”);向頁面寫資料出現亂碼
-
原因:浏覽器不知道伺服器響應的這些資料的編碼規則及内容類型
伺服器發出響應時,是按照utf-8方式進行編碼的;浏覽器解析響應資料時,進行解碼時沒有使用utf-8方式解碼,是以出現亂碼。
-
解決:response.setContentType(“text/html;charset=utf-8”);
伺服器需要告訴浏覽器響應資料的編碼規則及内容類型
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println(username);
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("中文");
}