1. 乱码原因
简单地讲,编码(encode)和解码(decode)使用的字符集不一致,就会导致乱码
- 服务器接收请求参数乱码原因:服务器接收数据解码时使用的字符集,与客户端发送数据编码时使用的字符集不一致
- 客户端接收响应数据乱码原因:客户端接收数据解码时使用的字符集,与服务器发送数据编码时使用的字符集不一致
2. 服务器获取GET请求queryString乱码解决方案
从Tomcat8开始,GET乱码问题已经由Tomcat自己解决了
如果是Tomcat7及之前,可以编辑conf/server.xml1
2
3
4
5<!-- 找到设置port="8080"的那个标签,添加URIEncoding="UTF-8"即可 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
如果使用的是Maven Tomcat插件,在<configuration>标签中设置<uriEncoding>属性即可1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<!-- 设置uriEncoding -->
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
3. 服务器获取POST请求体乱码解决方案
1 | // 在获取请求参数之前,先通过setCharacterEncoding设置编码 |
4. 客户端接收响应体乱码解决方案
在响应头不指定ContentType时,浏览器器默认使用的字符集与系统环境有关,例如Windows中文环境下,默认字符集是GBK(GB2312)
resp.getWriter() 获取输出流对象。Response是Tomcat实现的,编写Tomcat的不是中国人,他们指定了输出流的的默认字符集是IOS-8859-1。所以你用PrintWriter输出中文,使用IOS-8859-1,但是浏览器用GBK解码,肯定会乱码
解决方案如下:
1 | resp.setCharacterEncoding("UTF-8"); // 在获取输入流之前,设置响应体的编码 |
事实上,setCharacterEncoding()可以进一步省略,因为Tomcat在实现setContentType()时,不仅仅设置响应头了的ContentType,还同时设置了响应体的编码1
2
3resp.setContentType("text/html;charset=utf-8"); // 只要这一句就够了
PrintWriter out = resp.getWriter();
out.print("<h1>你好</h1>");