Servlet3:從根源瞭解並解決編碼問題
系列文章目錄
前言
你是否遇到無論使用什麼方法請求和響應總是亂碼的問題,這篇文章將帶你瞭解一切
URL編碼
在我們使用URL進行傳值時我們使用的格式為
?key1=value1&key2=value2
當我們要傳一些特殊字元以及中文時就必須使用百分號加傳入字元編碼的十六進位制表示形式,
舉個例子,寫一個jsp頁面編碼方式為GB2312,
<%@ page contentType="text/html;charset=GB2312" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="download" method="post">
檔名稱<input type="text" name="filename">
<input type="submit" value="提交" >
</form>
</body>
</html>
傳入"你好"點選提交
我們開啟除錯工具檢視http傳輸的真是編碼為%C4%E3%BA%C3
然後我們寫一個測試程式測試一下該字串解碼後是否是"你好"
public class test {
public static void main(String[] args) throws UnsupportedEncodingException {
System.out.println(URLDecoder.decode("%C4%E3%BA%C3", "Gb2312"));
}
}
檢視一下輸出,完全正確
如果我們將方法中的字符集改為utt8會怎麼樣
System.out.println(URLDecoder.decode("%C4%E3%BA%C3", "utf8"));
輸出一下,熟悉的字元來了
由於我們頁面通常使用utf8編碼格式,所以我把我的主頁編碼方式改回來再看一下"你好"的編碼,毫無疑問它變化了
編碼方式和字符集的區別
字符集和編碼方式區別很明顯,顧名思義,字符集就是字元的集合,如ASCII,GBK,BIG5,Unicode等,編碼方式是即可理解為定義在字符集上的對映規則對於unicode字符集,有utf8,utf16,utf32等多種編碼方式,但對於其他字符集比如,ASCII,GBK,GB2312等,不僅僅代表字符集,同時也代表了(預設的)的編碼方式
如何改變編碼方式
如果我們想改變一個資料的編碼方式,我們就必須先用原資料的編碼方式將源資料解碼為位元組資料,然後再使用我們需要的編碼方式進行編碼
Tomcat做了什麼
當使用者的請求到達伺服器時第一經手的是tomcat,它將資料自己預設的編碼方式處理請求和響應資料,傳給我們的自己定義的Servlet
POST請求亂碼
之所以要分POST請求和GET請求是因為post請求有響應體而get請求沒有響應體所以解決post請求亂碼有兩種方式
方式一
使用request.setCharacterEncoding()
方法,注意此方法的官方說明,
Overrides the name of the character encoding used in the body of this request.
翻譯過來就是"重寫此請求主體中使用的字元編碼的名稱",由於get請求沒有請求體,所以它自然不會對get請求有作用
此方法必須在獲取所有請求引數前呼叫才有效
來看一個小例子
我在後代獲取username的值並傳入資料庫,(注意資料庫的編碼方式設定為utf8),
我們先不使用這個方法看看結果
列印結果
資料庫結果
毫無疑問都是亂碼,接著使用這各方法設定為utf8看看結果
列印結果,為什麼亂碼?
資料庫結果,意料之中
那麼在這裡為什麼列印還是亂碼呢,因為當輸出到螢幕時,也需要轉換為我們系統的編碼方式才能不亂碼,那麼加上這句程式碼再試試
System.out.println(new String(username.getBytes(StandardCharsets.UTF_8),"GBK"));
列印結果不亂了,所以說不能因為列印結果亂碼就認定這個方法不行
方式二
方式二就是通過通過編碼解碼的方法來改變編碼方式,tomcat預設的編碼方式為
ISO-8859-1,我們只需要用這個編碼解碼再用utf8編碼即可
request.getParameter("username").getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)
GET請求亂碼
由於get請求沒有請求體所以只能用上述第二種方式
響應亂碼
解決響應亂碼也有兩步
第一步:設定響應體的編碼方式
response.setCharacterEncoding("UTF-8")
第二步:設定返回檔案的編碼方式
response.setContentType("text/html;charset=UTF-8")
這樣就能完全瞭解並解決編碼問題了
相關文章
- 編譯rocketmq-console並解決RejectedExecutionException問題編譯MQException
- 解決 requests 庫 URL 編碼問題
- 徹底解決Python編碼問題Python
- 帶您瞭解TRIZ理論解決問題的流程
- 解決中文亂碼問題
- mysql5.7.22設定中文編碼-解決亂碼問題LinuxMySqlLinux
- Netty原始碼學習6——netty編碼解碼器&粘包半包問題的解決Netty原始碼
- 簡單瞭解下JMM解決什麼問題
- java併發程式設計 --併發問題的根源及主要解決方法Java程式設計
- Linux 和 Windows 下編碼問題處理 codestyle 解決方法LinuxWindows
- 用深度學習解決競爭性編碼問題 | DeepMind深度學習
- 你解決的問題比你編寫的程式碼更重要!
- springmvc 解決中文亂碼問題SpringMVC
- MySql中文亂碼問題解決MySql
- Jmeter 解決中文亂碼問題JMeter
- Confluence 6 協同編輯問題解決
- 消除假確定性並解決實際問題
- JS、C#中URL編碼解碼問題JSC#
- MySQL直接匯出CSV檔案,並解決中文亂碼的問題MySql
- 從問題入手,深入瞭解JavaScript中原型與原型鏈JavaScript原型
- 資料編號+1 併發問題解決
- 解決Kali Linux 2020.1亂碼問題Linux
- TongWeb下亂碼問題解決思路Web
- java中亂碼問題解決方法Java
- ts程式碼提示很慢問題解決
- js解決url中文亂碼問題JS
- cat 輸出亂碼問題解決
- 解決plsql中中文亂碼問題SQL
- 例項解讀:MySQL並行複製如何解決特定的主從問題?MySql並行
- 從“股票問題”談動態規劃問題的解決思路動態規劃
- mysql主從複製配置與問題解決MySql
- 瞭解GaussDB效能調優之隱式轉換,解決慢SQL問題SQL
- 交叉編譯庫依賴問題的解決方法編譯
- matlab編譯exe問題具體解決辦法Matlab編譯
- 15個問題自查你真的瞭解java編譯優化嗎?Java編譯優化
- phantomjs截圖中文亂碼問題解決JS
- JavaWeb 亂碼問題終極解決方案!JavaWeb
- 自定義RedisTemplate,解決Redis亂碼問題Redis