本帖最后由 liukun11 于 2017-8-24 17:32 编辑
编码问题是很多初学者在 Web 开发过程中经常会遇到的问题,很多同学在记忆的时候容易出现混淆,或是虽然能够机械的记住解决的代码,但是对乱码出现的原因以及解决的原理未作过了解。因此本文这部分内容作一个简单的总结和解释。
请求中文乱码
HTTP 请求中,最常用的请求方式为 GET 和 POST。请求参数会随着不同的请求方式出现在不同的位置,所以对于中文乱码的处理方式也不一样。
GET 请求中文参数乱码解决
GET 方式提交参数时,参数是直接出现在 URL 中的,对于 GET 请求,中文参数乱码问题解决方式有3种。
1.修改 Tomcat 编码。
Tomcat 安装路径–> conf –>server.xml –> Connector 标签–> 增加 URIEncoding 属性
1 | <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/> | 通常不建议使用这种方式,因为一个采用Tomcat8.0 之前版本服务器的老项目,代码中可能已经处理了GET请求的乱码问题,采用这种方式反而会导致乱码的出现。Tomcat8以及以上版本已经将默认编码修改为 UTF-8 因此不用修改。
2. 通过 URLEncoder 和 URLDecoder 进行编解码操作。
1
2 | String encode = URLEncoder.encode(request.getParameter("name"),"ISO-8859-1");
String name = URLDecoder.decode(encode,"UTF-8"); | 代码解释:
GET 请求的参数是出现在 URL 中的 QueryString 部分的,URL 中如果含有中文等非 ASCII 字符,则浏览器会对它们进行 URLEncode,然后发送给服务器,在通过request.getParameter(“name”) 取出时又会对该name 对应的参数进行 URLDecode。通常在进行 URLEncode 的时候采用的编码为 UTF-8,而在 URLDecode 的时候会采用 Tomcat 服务器的默认编码 ISO-8859-1,编码和解码所采用的编码方式不一致,所以出现乱码。既然通过request.getParameter(“name”) 得到了一个采用ISO-8859-1 进行 URLDecode 的乱码,那么我们可以对该乱码通过 ISO-8859-1 进行 URLEncode,此时的值就是浏览器最初提交到后台的通过 UTF-8 URLEncode 后的数据。然后我们通过与浏览器一致的 UTF-8 编码对该数据进行解码。两端编码一致,乱码问题就得到了解决。
Talk is cheap,Show you the code.
我们通过下面的代码来解释乱码出现到解决的过程,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | @Test
public void test1()throws Exception {
// 1,原始中文参数
String parameter = "中文";
System.out.println("原始中文参数:"+parameter);
// 2,浏览器通过 UTF-8 进行 URLEncode
String browerEncodeParameter = URLEncoder.encode(parameter, "UTF-8");
System.out.println("浏览器通过 UTF-8 进行 URLEncode 后的值:" +browerEncodeParameter);
// 3,通过 ISO-8859-1 进行 URLDecode
String serverDecodeParameter = URLDecoder.decode(browerEncodeParameter, "ISO-8859-1");
System.out.println("直接取出时通过 ISO-8859-1 进行 URLDecode 后得到的乱码:"+serverDecodeParameter);
// 4,手动通过 ISO-8859-1 对乱码进行 URLEncode
String codeEncodeParameter = URLEncoder.encode(serverDecodeParameter,"ISO-8859-1");
System.out.println("手动对乱码通过 ISO-8859-1 进行 URLEncode 得到的浏览器原始提交的值:"+codeEncodeParameter);
// 5,手动通过 UTF-8 对步骤4得到的值进行 URLDecode 后得到正确中文参数
String codeDecodeParameter = URLDecoder.decode(codeEncodeParameter,"UTF-8");
System.out.println("手动通过 UTF-8 进行 URLDecode 后得到的正确中文参数:"+codeDecodeParameter);
} | 执行结果:
1
2
3
4
5 | 原始中文参数: 中文
浏览器通过 UTF-8 进行 URLEncode 后的值: %E4%B8%AD%E6%96%87
直接取出时通过 ISO-8859-1 进行 URLDecode 后得到的乱码: 䏿
手动对乱码通过 ISO-8859-1 进行 URLEncode 得到的浏览器原始提交的值: %E4%B8%AD%E6%96%87
手动通过 UTF-8 进行 URLDecode 后得到的正确中文参数: 中文 |
由于篇幅限制,剩余内容见 【重庆校区】WEB中文乱码总结(下)
|