汉字传值奇数乱码问题解决策略, 转码编码解码
这两天写一个项目遇到一个很怪异的现象,就是在url中汉字传值,如果是奇数个汉字则出现编码错误。先说下环境:
?
前台页面试gb2312编码,后台的filter是gbk,web server是nginx+resin,nginx用的是操作系统编码,编码是gbk
?
在输入http://www.我的域名.com/search/searchByName.action?query=%C1%AC%C1%AC%BF%B4?? (1)
时后台不需要做处理,返回字符串正常
?
再输入http://www.我的域名.com/search/searchByName.action?query=连连看 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(2)
时后台就显示乱码
?
我分别用chrome、firefox、ie8做了测试,结果虽然是乱码还各有特色
?
最初,在网上搜索解决方案,不过大部分都是一个来源,也就是让你在页面上先对汉字url encode一下然后再传值,但是这种情况不符合我的需求,我是要在浏览器中直接输入url,汉字传值;
?
解决方案一,在nginx中配置,将传递过来的url进行重写,让参数以重叠的方式向后台传送,比如原来是"query=你好啊",重写为"query = 你好啊你好啊",这样可以避免奇数个乱码问题,不过这有一个问题,就是和web server的耦合性太高,只要有汉字传值,就得重写nginx配置文件,不可取。
?
解决方案二,在后台发现,取出的parameter在utf8转换成gbk时,如果字符串.getbytes()是奇数个,最后一个byte会被吞掉,信息损失了,就没法转换回来了。很烦人,这时候在同事的启发下,发现request.getQueryString(),也可以得到参数,并且都是被转码过的,形如“query=%e7%be%8e%e5%a5%b3”,这个是没有被gbk过滤的,所以就通过处理这个字符串获取到了没有信息损失的编码。不过这时还有个问题,页面输入(1)(2)两个链接时后台要拿到相同的汉字,但是他们被编码后显示的编码值却不同,就是这个时候只要通过判断是否为utf8的url(此时有汉字传值),如下代码:
?
String agent = request.getHeader("User-Agent");if(agent.indexOf("MSIE")!=-1){//ie情况比较特殊,不过此时在parameters中是正常的query = request.getParameter("query");}?这样在ie下拿到的汉字也就可以正常的显示了。
?
?
解决方案三:觉得最好的解决方案还是写个filter,现在项目比较紧张,以后要写,这样就可以忽略掉具体的请求,从整体层次进行解决问题。大致思路就是将方案二的解决办法浓缩到filter中。以后再写
?
还有一些感想,觉得chrome也不是那么完美,汉字传值不自动转码,给开发造成不少麻烦,还是firefox比较强大~