网站开发进阶 (三十三) 中文字符编码问题解决总结

一、前言
遇到的问题千奇百怪,在往 mysql 数据表存储带有中文字符的字符串时显示乱码。经过代码输出测试发现插入语句如下:

在数据库内查询,发现存储的内容为乱码。

尝试在 mysql 中直接插入语句。如下:
由上面的数据表可以看出,存储正常。而且在页面显示正常。

为此,可以判定是数据表的字符编码出现了问题。
找了半天,原来问题出在这,可坑苦我了,连接数据库时未指定编码方式!!
jdbc:mysql://localhost:3308/lmapp?useUnicode=true&characterEncoding=utf8
在进行数据库连接时一定要指定编码方式!(多么痛的领悟~)
团队开发时,有一套完善的编码规范至关重要!
不怕 BOSS 的 BUG,就怕没有良好编码风格的队友!
二、继续
在客户端一切正常,但是放到服务器上,还是出现了问题。

从输出信息可以判断在服务器端,获取中文字符时就已经出现了问题,而与数据库并无关系。回到程序中,相应字符编码如下:

改用默认编码String medname=new String(medname1.getBytes(),"UTF-8");
后,服务端输出如下:

部分中文字符得到了解析。
改变一下思路,首先查看传入参数的编码格式。有关编码格式的工具类,详见博文《java 判断字符串编码类型》。
在本地:

服务端:

可见两者将在利用 http post 请求方式传参时所使用的编码方式不同,但是这是一个项目,编码方式相同毋庸置疑。
request.setCharacterEncoding("UTF-8");
三、困惑
既然服务端传参时本身就是 UTF-8,但是其内容还是乱码!
转换编码方式:
String medname=new String(medname1.getBytes("GBK"),"UTF-8");

可发现,只有 4 个中文字符得到了正确转义。存在中文字符编码转换过程中字符丢失现象。有关字符编码格式,详见博文《String.getBytes()方法中的中文编码问题》。
再次更换编码方式,将页面显示编码改为“GBK”,这样中文字符就可以正常显示了。直接在请求参数中即可获取到正确的参数(编码方式为 GBK),而无需再次转码。但是在本地测试时仍然出现乱码现象,因为其编码方式为 ISO-8859-1。


同样,在药品说明书展示时同样需要指定编码方式为“GBK”。这样自己就有一个大大的疑惑了:“为何本地与服务器上的编码方式会不同?”详见博文《编码中的 setCharacterEncoding 理解》。在 Tomcat5.0 中,默认情况下使用 ISO- 8859-1 对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码(解码),而不使用该参数对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码(解码)。这样本地输出的编码方式为 ISO8859-1 就不足为奇了。
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/b24f80f1669dca1e689354a47】。文章转载请联系作者。
评论