我們在javaWeb項目時,使用doget和dopost總是會出現各種原因的中文亂碼問題,樓主在查閱大量資料後,將爲什麼有這樣的問題,和如何解決這種問題做個總結。
思維導圖:
1. 應答亂碼處理(response輸出頁面時亂碼)
1.1 問題:
輸出到頁面時中文會亂碼
後端代碼:
PrintWriter out = response.getWriter();
out.println("你好");
前端顯示:
1.2 原因
沒有設置HttpServletResponse使用哪種編碼,默認編碼跟瀏覽器解碼不匹配。
1.3 解決方案:
方案1:
在PrintWriter out = response.getWriter();
之前添加這兩句:
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
//設置HttpServletResponse使用UTF-8編碼
response.setCharacterEncoding("UTF-8");
//通知瀏覽器使用UTF-8解碼
response.setHeader("Content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
方案2:
或者在之前添加這一句:
response.setContentType("text/html;charset=utf-8");
//包含方案1的兩種功能
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
以上兩種方案添加其中之一後前端顯示:
2. 請求亂碼處理(request.getParameter("xxx")得到參數時亂碼)
2.1 問題:
在java程序內部拿到的中文參數會是亂碼
前端代碼:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<form action="RequestParamsServlet" method="post">
用戶名:<input name="username" type="text">
密碼:<input name="password" type="text">
愛好:
<input type="checkbox" name="hobby" value="運動">運動
<input type="checkbox" name="hobby" value="游泳">游泳
<input type="checkbox" name="hobby" value="打乒乓球">打乒乓球
<input type="submit">
</form>
</body>
</html>
前端顯示:
後端測試:
String username=request.getParameter("username");//傳來的是中文參數
System.out.println(username);//控制檯輸出的中文亂碼
控制檯結果:
2.2 原因
2.2.1 doGet和doPost的不同
doPost:post提交是通過HTTP post機制,將表單內各個字段與其內容放置在HTML header內一起傳送到action屬性所指的URL地址。用戶看不到這個過程。簡單來說post提交是跟隨request請求體的。
doGet:get提交是把參數數據隊列加到提交表單的action屬性所指的URL中,值和表單內各個字段對應,在URL中可以看到。簡單來說get提交是不跟隨requset請求體的。
2.2.2 瀏覽器和java程序內部的編碼解碼方式不同
瀏覽器設置的編碼方式是UTF-8,而java程序內部設置的默認解碼方式是ISO-8859-1,兩者不同則會造成亂碼;
而由於post提交和get提交的不同,兩者解決中文亂碼的方式也不同。
2.3 doPost獲取參數解決方案
post提交經過請求體,對請求體設置解碼方式即可解決亂碼
在方法體開頭添加:
//設置request對象的解碼方式
request.setCharacterEncoding("utf-8");
2.4 doGet獲取參數解決方案(難點,分tomcat版本)
get提交不經過請求體而是通過URL傳參,設置requset解碼方式無效,且tomcat版本不同解決方法不同,8.0版本是分界線
2.4.1 tomcat8.0版本之前:
tomcat8.0之前對URL的默認解碼方式是ISO-8859-1,而瀏覽器的編碼方式是UTF-8,造成亂碼。
方案1:
通過new String()方式轉碼:用getBytes(“ISO-8859-1“)拿到原編碼的byte數組,再通過new一個String轉成utf-8編碼
String username=new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");
方案2:
設置tomcat默認編碼爲UTF-8:修改tomcat目錄下/conf/server.xml文件,增加 URIEncoding="UTF-8",此後不需要轉碼操作,參數不會亂碼,但此方法操作的是服務器端,會造成適配影響,不推薦使用。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
方案3:
使用過濾器方法,原理跟方案1一樣,只不過不用每一個參數都寫一次轉碼
方案4:
提供一個思路,get提交幾乎每一點都比不上post提交,那麼就使用post提交方式就好了。
2.4.2 tomcat8.0版本之後:
tomcat8.0之後對URL的默認解碼方式是UTF-8,而瀏覽器的編碼方式是UTF-8,不會造成亂碼
不需要再轉碼(切記,槓掉):String username=new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");
此時我們就不要傻乎乎的用getBytes(“ISO-8859-1“)解碼了,反而會出現解碼錯誤,造成亂碼,直接使用參數即可。
3. 控制檯亂碼
3.1 控制檯顯示tomcat服務亂碼
3.1.1 問題:
啓動tomcat還有運行時tomcat會產生亂碼,原因是IntelliJ IDEA和tomcat的編碼解碼不一致造成。
現象如下:
3.1.2 原因?
IntelliJ IDEA控制檯默認解碼是GBK,而tomcat對控制檯的默認編碼是UTF-8,把一方改成一致即可解決,推薦修改tomcat對控制檯的默認編碼爲GBK,因爲windows的cmd控制檯的默認解碼也是GBK。
3.1.3 解決方案
修改tomcat目錄下/conf/logging.properties,原先encoding=UTF-8,建議全部改成GBK,全無亂碼
修改後
3.2 控制檯打印亂碼 (system.out.println打印的亂碼)
3.2.1問題:
tomcat啓動和運行時亂碼在上方解決後,system.out.println打印server控制檯亂碼怎麼辦?
例如:tomcat7環境下
兩個轉碼成UTF-8的字符串張三正常,而本身輸出的字符串出現亂碼
3.2.2 原因
File Encodings編碼設置不一致。
3.2.3 解決方案:
打開settings
點擊convert
再次啓動:
4.具體實例
請參考本人另一篇博客:tomcat7和tomcat9解除中文亂碼具體實例
親測完全正確哦,有錯誤的同學注意查看tomcat的server.xml是不是加了多餘的配置,或者idea編輯器的字符編碼配置有錯。
相信認真讀到這裏,關於中文亂碼的問題已經瞭解
如果對你有所幫助,點贊支持一下作者~