天天看點

【Servlet】請求和響應亂碼字元編碼get請求亂碼post請求亂碼響應亂碼

文章目錄

  • 字元編碼
  • 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("中文");
	}