参考资料:http://m.oschina.net/blog/376339
乱码的本质是涉及到编解码的几个过程所用的编码方式不一样。
一、从服务端到客户端
在整个服务器端数据返回到浏览器的过程中,涉及到三次编码:
第一次:java文件以什么编码存放在硬盘中
第二次:字符串是以什么编码方式转换成字节数组的,若未指定@RequestMapping的produces属性,同时也未给StringHttpMessageConverter指定编码方式,则字符串默认是以ISO-8859-1形式转换成字节数组的。
可以通过produces = "text/html;charset=UTF-8"来指定编码:@RequestMapping(value = "/register", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
第三次:数据发送给浏览器后,浏览器接收到一堆字节数组,浏览器又是以什么编码方式来解码的。
只有三者统一才不会出现乱码。具体见上述参考文章。
二、客户端到服务端
此过程涉及到两次编码:
第一次:当你输入http://localhost:8080/test?name=中国 的时候,浏览器将以什么样的编码方式将中国转化成字节数组,这称为URL编码 。不同的浏览器会采用不同编码方式来将 中国 转换成字节数组,一般为UTF-8;而程序中按默认编码对中文进行url encode,中文环境一般为GBK,这点应注意。
第二次:当浏览器发送请求时,服务器是以请求的content-type来解析请求数据的,当浏览器请求没有指定content-type时,不同的服务器应该有不同的策略,并且可以进行设置。
如Tomcat服务器,默认采用的是ISO-8859-1(不支持中文),可以通过修改Tomcat的conf/server.xml文件,在Connector标签中增加 URIEncoding='UTF-8' 来修改Tomcat的默认编码解析方式(在Tomcat 8中默认已为UTF-8,这个应特别注意,否则经下面所说的代码方法处理后的代码放在Tomcat8反而会乱码,笔者就因为这个原因导致本机能正确跑的代码放在生产环境中后跑的结果不正确,浪费了好多时间);
对于默认采用的是ISO-8859-1的服务器,此也可以通过在代码中解码再编码数据来解决乱码:
// GET方式:http的url传过来的数据Tomcat默认是用iso-8859-1(不支持中文)解码的,故数据先用iso-8859-1编码得到原文后再用与url相同的编码方法解码 userName = new String(userName.getBytes("iso8859-1"), "utf-8");
三、java Servlet中中文乱码
1、post
对于post方法中的乱码,浏览器通常是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收。
可以通过request.setCharacterEncoding("utf-8");解决;或在代码中解码再编码数据来解决乱码
2、get
在代码中解码再编码数据来解决乱码