【JavaWeb開發】Servlet徹底解決開發中請求(get/post)、應答以及控制檯中文亂碼問題

我們在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一樣,只不過不用每一個參數都寫一次轉碼

過濾器解決servlet中文亂碼

方案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編輯器的字符編碼配置有錯。

相信認真讀到這裏,關於中文亂碼的問題已經瞭解

如果對你有所幫助,點贊支持一下作者~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章