前两天同事问了我一个中文乱码的问题。他写了一个json请求的接口,通过浏览器请求接口的时候,返回的json中包含的中文显示了乱码。后来使用jmeter进行测试时也发现返回的是乱码。
之前也遇到过几次Java/JSP中文乱码的问题,知道乱码通常发生在字节流和字符相互转换的过程中。检查了一些这个接口涉及到的几次字节流转换的地方都没发现问题。我这个同事还是挺细心的,注意了统一使用UTF8进行编码,并且在输出接口内容时也添加了“response.setCharacterEncoding(“UTF-8”);”这样的代码。所以尝试将问题定位在浏览器显式前后:在PrintWriter输出前打印日志,如果中文在日志上可以正确显示那么问题就应该是出在浏览器端了,否则就从继续从后端找原因。结果还没观察日志呢,另一个同事查看了一下浏览器的内容编码设置,发现浏览器的内容编码设置的是GBK。问题就这样解决了:将浏览器的内容编码设置改为UTF8后问题就解决了。
问题是解决了,但是产生了一个疑问:为什么我们的程序没有提示浏览器该使用什么样的编码来解析接收到的信息呢。查了一些资料知道了该怎么设置就能完美解决这个问题了。这涉及到ServletResponse设置编码的几个方法。ServletResponse设置编码有如下三个方法:
- response.setCharacterEncoding(“UTF-8”);
- response.setContentType(“text/html;charset=UTF-8”);
- response.setLocale(new java.util.Locale(“zh”,”CN”));
简单解释下这几个方法及其优先级:
- 第一种方法只能用来设置out输出流中所采用的编码,但是它的优先权最高,可以覆盖后面两种方法中的设置;
- 第二中方法可以设置out输出流中字符的编码方式,也可以设置浏览器接收到这些字符后以什么编码方式来解码,它的优先权低于第一种方法,但高于第三种方法;
- 第三种方法只能用来设置out输出流中字符的编码方式,但是它的优先权最低,在已经使用前两种方法中的一个设置了编码方式以后,它就被覆盖而不起作用了。
所以,使用response.setContentType可以完美解决前面提到的那个问题。
此外,还需要注意使用的ContentType,因为我同事写的接口返回的是json,所以他使用的content-type应该是“application/json”。
就这样!
########
发表评论