java使用URLDecoder和URLEncoder對(duì)中文字符進(jìn)行編碼和解碼
摘要:
URLDecoder 和 URLEncoder 用于完成普通字符串 和 application/x-www-form-urlencoded MIME 字符串之間的相互轉(zhuǎn)換。在本文中,我們以使用URLDecoder解決GET請(qǐng)求中文亂碼問題為場(chǎng)景說明 URLDecoder/URLEncoder 的用法,并給出了 application/x-www-form-urlencoded MIME 字符串的編碼規(guī)則。
一. URLDecoder/URLEncoder 使用場(chǎng)景概述
URLDecoder 和 URLEncoder 用于完成普通字符串 和 application/x-www-form-urlencoded MIME 字符串之間的相互轉(zhuǎn)換。在介紹 application/x-www-form-urlencoded MIME 字符串之前,我們先考慮如下場(chǎng)景,如下圖所示:
我們知道,在我們向客戶端發(fā)起請(qǐng)求時(shí),瀏覽器會(huì)根據(jù)請(qǐng)求URL生成相應(yīng)的請(qǐng)求報(bào)文發(fā)送給服務(wù)器。在這個(gè)過程中,如果我們?cè)跒g覽器中的地址欄中所輸入的URL包含中文字符時(shí),瀏覽器首先會(huì)將這些中文字符進(jìn)行編碼然后再發(fā)送給服務(wù)器。實(shí)際上,瀏覽器會(huì)將它們轉(zhuǎn)換為 application/x-www-form-urlencoded MIME 字符串,如下圖所示:
更確切的,當(dāng)URL地址里包含非西歐字符的字符串時(shí),瀏覽器都會(huì)將這些非西歐字符串轉(zhuǎn)換成application/x-www-form-urlencoded MIME 字符串。在開發(fā)過程中,我們可能涉及將普通字符串和這種特殊字符串的相關(guān)轉(zhuǎn)換,這就需要使用 URLDecoder 和 URLEncoder類進(jìn)行實(shí)現(xiàn),其中:
- URLDecoder類包含一個(gè)decode(String s,String enc)靜態(tài)方法,它可以將application/x-www-form-urlencoded MIME字符串轉(zhuǎn)成普通字符串;
- URLEncoder類包含一個(gè)encode(String s,String enc)靜態(tài)方法,它可以將普通字符串轉(zhuǎn)換成application/x-www-form-urlencoded MIME字符串。
下面程序示范了普通字符串轉(zhuǎn)與 application/x-www-form-urlencoded MIME 字符串之間的轉(zhuǎn)化。
public class URLDecoderTest { public static void main(String[] args) throws Exception { // 將application/x-www-form-urlencoded字符串轉(zhuǎn)換成普通字符串 // 其中的字符串直接從上圖所示窗口復(fù)制過來,chrome 默認(rèn)用 UTF-8 字符集進(jìn)行編碼,所以也應(yīng)該用對(duì)應(yīng)的字符集解碼 System.out.println("采用UTF-8字符集進(jìn)行解碼:"); String keyWord = URLDecoder.decode("%E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6+Rico", "UTF-8"); System.out.println(keyWord); System.out.println("\n 采用GBK字符集進(jìn)行解碼:"); System.out.println(URLDecoder.decode("%E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6+Rico", "GBK")); // 將普通字符串轉(zhuǎn)換成application/x-www-form-urlencoded字符串 System.out.println("\n 采用utf-8字符集:"); String urlStr = URLEncoder.encode("天津大學(xué)", "utf-8"); System.out.println(urlStr); System.out.println("\n 采用GBK字符集:"); String urlStr2 = URLEncoder.encode("天津大學(xué)", "GBK"); System.out.println(urlStr2); } }/* Output: 采用UTF-8字符集進(jìn)行解碼: 天津大學(xué) Rico 采用GBK字符集進(jìn)行解碼: 澶╂觸澶у Rico 采用utf-8字符集: %E5%A4%A9%E6%B4%A5%E5%A4%A7%E5%AD%A6 采用GBK字符集: %CC%EC%BD%F2%B4%F3%D1%A7 *///:~
特別地,僅包含西歐字符的普通字符串和application/x-www-form-urlencoded MIME字符串無須轉(zhuǎn)換,而包含中文字符的普通字符串則需要轉(zhuǎn)換,轉(zhuǎn)換的方法是每個(gè)中文字符占2個(gè)字節(jié),每個(gè)字節(jié)可以轉(zhuǎn)換成2個(gè)十六進(jìn)制的數(shù)字,所以每個(gè)中文字符將轉(zhuǎn)換成“%XX%XX”的形式。當(dāng)然,采用不同的字符集時(shí),每個(gè)中文字符對(duì)應(yīng)的字節(jié)數(shù)并不完全相同,所以使用URLEncoder和URLDecoder進(jìn)行轉(zhuǎn)換時(shí)也需要指定字符集。特別地,字符串應(yīng)以同樣的字符集進(jìn)行編碼和解碼,否則會(huì)產(chǎn)生意想不到的結(jié)果,如上述程序示例所示。
二. 解決GET請(qǐng)求中文亂碼問題
URLDecoder的一個(gè)應(yīng)用場(chǎng)景就是解決GET請(qǐng)求的中文亂碼問題,如下述代碼所示:
<%@page import="java.net.URLDecoder"%> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>Test</title> </head> <body> <% String param1 = request.getQueryString(); String param2 = URLDecoder.decode(param1, "utf-8"); out.print(param2.split("=")[1] + "<br>"); %> </body> </html>
特別需要注意的是,使用此方式對(duì)GET請(qǐng)求參數(shù)進(jìn)行解碼時(shí),我們必須先對(duì) request.getQueryString 方法的返回值(例如,“name=摩羯西門吹雪”)進(jìn)行解碼,然后再?gòu)闹腥〕鑫覀兯枰膮?shù)值。如果先取出參數(shù)值,然后再對(duì)參數(shù)值進(jìn)行解碼,則我們將得到亂碼,如下圖所示:
此外,對(duì)于包含中文字符的POST請(qǐng)求參數(shù),我們只需在獲取請(qǐng)求參數(shù)前通過以下代碼語句進(jìn)行轉(zhuǎn)碼即可:
request.setCharacterEncoding("utf-8");
三. URLEncoder & URLDecoder
對(duì) String 編碼時(shí),使用以下規(guī)則:
- 字母、數(shù)字和字符, “a” 到 “z”、”A” 到 “Z” 和 “0” 到 “9” 保持不變;
- 特殊字符 “.”、”-“、”*” 和 “_” 保持不變;
- 空格字符 ” ” 轉(zhuǎn)換為一個(gè)加號(hào) “+”。
除此之外,所有的其他字符都是不安全的。因此需要使用一些編碼機(jī)制將它們轉(zhuǎn)換為一個(gè)或多個(gè)字節(jié),每個(gè)字節(jié)用一個(gè)包含 3 個(gè)字符的字符串 “%xy” 表示,其中 xy 為該字節(jié)的兩位十六進(jìn)制表示形式,推薦的編碼機(jī)制是 UTF-8。例如,使用 UTF-8 編碼機(jī)制,字符串 “The string ü@foo-bar” 將轉(zhuǎn)換為 “The+string+%C3%BC%40foo-bar”,因?yàn)樵?UTF-8 中,字符 ü 編碼為兩個(gè)字節(jié),C3 (十六進(jìn)制)和 BC (十六進(jìn)制),字符 @ 編碼為一個(gè)字節(jié) 40 (十六進(jìn)制)。
關(guān)于 URLDecoder 類的使用,轉(zhuǎn)換過程正好與 URLEncoder 類使用的過程相反,此不贅述。
關(guān)于JSP中文亂碼更多的介紹,包括 頁面亂碼、參數(shù)亂碼、表單亂碼、源文件亂碼 等知識(shí),見我的另外兩篇博客:《JSP中文亂碼問題終極解決方案(上)》 和 《JSP中文亂碼問題終極解決方案(下)》。
引用
使用URLDecoder和URLEncoder對(duì)中文進(jìn)行處理
到此這篇關(guān)于java使用URLDecoder和URLEncoder對(duì)中文字符進(jìn)行編碼和解碼的文章就介紹到這了,更多相關(guān)java 文字符編碼解碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)簡(jiǎn)單的聊天室功能
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06使用MyBatisPlus自動(dòng)生成代碼后tomcat運(yùn)行報(bào)錯(cuò)的問題及解決方法
這篇文章主要介紹了使用MyBatisPlus自動(dòng)生成代碼后tomcat運(yùn)行報(bào)錯(cuò)的問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Java動(dòng)態(tài)規(guī)劃之硬幣找零問題實(shí)現(xiàn)代碼
這篇文章主要介紹了Java動(dòng)態(tài)規(guī)劃之硬幣找零問題實(shí)現(xiàn)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11SpringBoot+jsp項(xiàng)目啟動(dòng)出現(xiàn)404的解決方法
這篇文章主要介紹了SpringBoot+jsp項(xiàng)目啟動(dòng)出現(xiàn)404的解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03SpringBoot多種自定義錯(cuò)誤頁面方式小結(jié)
這篇文章主要介紹了SpringBoot多種自定義錯(cuò)誤頁面方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11JVM分配和回收堆外內(nèi)存的方式與注意點(diǎn)
JVM啟動(dòng)時(shí)分配的內(nèi)存稱為堆內(nèi)存,與之相對(duì)的,在代碼中還可以使用堆外內(nèi)存,比如Netty,廣泛使用了堆外內(nèi)存,下面這篇文章主要給大家介紹了關(guān)于JVM分配和回收堆外內(nèi)存的方式與注意點(diǎn),需要的朋友可以參考下2022-07-07Java多例Bean的應(yīng)用場(chǎng)景-easyExcel導(dǎo)入
EasyExcel 是一個(gè)基于 Java 的簡(jiǎn)單、省內(nèi)存的讀寫 Excel 的開源項(xiàng)目。這篇文章主要介紹了用easyExcel導(dǎo)入Java Bean的應(yīng)用場(chǎng)景,感興趣的朋友可以參考閱讀2023-04-04mybatisplus中EntityWrapper的常用方法
這篇文章主要介紹了mybatisplus中EntityWrapper的常用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java數(shù)據(jù)結(jié)構(gòu)中雙向鏈表的實(shí)現(xiàn)
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中雙向鏈表的實(shí)現(xiàn),雙向鏈表是一種常見的數(shù)據(jù)結(jié)構(gòu),它允許在鏈表中的任意位置進(jìn)行高效的插入和刪除操作,需要的朋友可以參考下2022-05-05