简单的介绍下背景,APP访问服务器,需要经过部署在DMZ(非军事冲突区)的代理,最近有个需求需要使用get请求方式请求web端jsp页面,返回数据为json格式。以前在使用get请求数据时,参数没有出现中文,参数有中文的都使用了post的方式,由于特殊的原因,这次放弃了post方式。在get中传递中文参数,出现乱码情况,造成代理后台接收数据错误,无法返回数据。下面就简单的记录下修复的过程。
中文乱码说实话,每个程序员都会遇到,说到底,就是编解码格式不对造成,首先查看了,代理和主程序默认的编码格式,可利用 HttpServletRequet.getCharacterEncoding()查看,发现是GBK格式,于是就用value = URLDecode.decode("value","GBK")解码,(假设Value 就是接受的中文参数)发现依旧乱码,于是又对该数据进行了 String decodeValue = new String (value.getBytes("GBK"),"UTF-8")操作,发现竟然可以了,但是出现偶数中文正常,奇数中文依旧乱码的格式,头痛啊,GBK 是两个字节表示一个汉字,UTF-8三个字节表示一个汉字,其实说白了,偶数汉字解析成功纯属侥幸,不过可以利用该特征,做一点小小的坏事,既然偶数可以解析成功,为何每次传参数不传偶数个那,只需在后台解析成功后在去掉多余的汉字就OK了,例如,你本来想传单个汉字‘中’,那么实际你就可以传‘中中’。但是这种方式,不管是性能还是其他各个方面,都不是我们想要的结果。于是,继续探索。
发现我们在浏览器直接传中文,用HttpServletRequet.getParameter()接受参数时,已经是乱码了,也就是说在这个过程中,已经有了一次编解码的过程,利用encodeURIComponent('上海')获得到编码后的数据"%E4%B8%8A%E6%B5%B7",当做参数传入,发现后台接受的依然是乱码,但是乱码不同了,于是用encodeURIComponent对参数进行了2次编码,代理后台接受到数据是"%E4%B8%8A%E6%B5%B7"也就是用encodeURIComponent('上海')编码一次后数据,同时也说明了代理后台在接受参数时,已经进行了一次解码。因为要与主程序交互,代理程序在与主程序传参时也需要传递编码后的参数。既APP传递参数时需要进行三次编码。流程如下:
APP------参数需三次编码------->代理--------参数需两次编码--------->主系统(参数为正常汉字)
既APP传递参数时需要对中文进行如下操作:encodeURIComponent(encodeURIComponent(encodeURIComponent('上海'))
网友评论