使用http请求,中文乱码问题--解决方法
2017-08-24 17:48
267 查看
最近写了一个客户端向服务器端发起http请求的功能,服务器端返回的数据中包含中文,奇怪的是中文个数是偶数个的时候,没有乱码,但是奇数个数时,最后一个汉字会编程问号?,以前也出现过类似问题,也解决了,但是没有记录,现在一下子想不到该怎么解决了,
代码是这样的:
服务器端部分代码:
String str = "这个是中文乱码测试代码" ;
System.out.println("服务器返回的结果:");
System.out.println(str);
PrintWriter writer = resp.getWriter();
writer.write(str);
writer.flush();
接受端部分代码:
String result = HttpUtil.postToRest(HttpUtil.postUrl, HttpUtil.opttype,
"service2", HttpUtil.data);
System.out.println("掉用方接收到的数据1:" + result);
请求后返回数据,控制台打印如下:
服务器返回的结果:
这个是中文乱码测试代码
掉用方接收到的数据1:?????????????????
在网上找了一些也没有发现解决方法,大概意思都是说是因为tomcat使用的是gbk编码,gbk一个汉字两个字节,utf-8一个汉字三个字节,然后经过转码就会发生?乱码问题,如其中有一篇博客是这样讲的:
UTF-8中,一个汉字3个字节,GBK中一个汉字2个字节,我好像明白了什么。。
因为jetty容器默认是按照系统编码来决定容器编码,前提是没有自己修改启动编码,而公司里我台PC是windows的,好像默认GBK的,反正我对windows绯闻也挺多的,于是这里有一个问题,比如jetty接受到了一串经过UTF-8编码的汉字:
我很好
jetty收到的最原始的二进制数组是这样的:
[-26, -120, -111, -27, -66, -120, -27, -91, -67]
当然这不是最原始的,最原始的0和1,当然为了好看就算他是最原始的吧,下一步jetty要开始编码了,按照jetty的GBK编码,他按照2个字节一个汉字的格式去编码,于是出现了这样的组合:
[-26, -120] [ -111, -27] [-66, -120] [-27, -91] [-67]
前面每两个字节都能找到对应的汉字,最后jetty发现最后居然只有一个字节,找不到对应的汉字,心里想这SB是哪来的,于是jetty放弃它了,把它赶出去,把63丢过去,于是最后的组合成了:
[-26, -120] [ -111, -27] [-66, -120] [-27, -91] [63]
经过GBK的格式编码,两个字节对应一个汉字,就显示出了这样的东西:
骞茶帿瀛?
会出现5个,因为每2个字节代表一个汉字,最后一个字节是63,对应的符号是?,就出现了上面的东西,于是我对它做了强制的UTF-8编码,导致上面的二进制数组重新组合,经过UTF-8的组合之后,二进制数组成了这样:
[-26, -120, -111] [-27, -66, -120] [-27, -91, 63]
再经过UTF-8显示之后,变成了这样:
我很�?
前6个字节能够正常的显示出汉字,因为那就是真正的数据,然而最后3个字节,已经被GBK处理了,替换过了,即使使用UTF-8也无法还原它原来的容貌,于是它就显示成了上面的样子,但是为什么偶数不会出错?
因为偶数能够被GBK正常的解码,也就是如果汉字是偶数,UTF-8和GBK是等同的,但是如果是奇数,则就出问题了,这也是传说中的最后一个汉字乱码的问题,因为最后一个 字节始终是63,要解决这个问题,必须要治标还要治本,项目中必须全程保证编码一致性。
文章摘自:http://www.cnblogs.com/gudi/p/4086183.html
折腾了好一会时间,忽然想到以前使用的是
java.net.URLEncoder
就是说服务器端在返回带有中文数据的时候,将字符串使用URLEncoder.encode(str)加码,
然后在调用接口端,接收到数据
java.net.URLDecoder
也就是URLDecoder.decode(str)技术解码,这样就可以完美的解决问题了。
具体代码如下:
服务器端部分返回代码:
String str= "这个是中文乱码测试代码" ;
str = URLEncoder.encode(str);
System.out.println("服务器返回的结果:");
System.out.println(str);
PrintWriter writer = resp.getWriter();
writer.write(str);
writer.flush();
调用端部分代码:
String result = HttpUtil.postToRest(HttpUtil.postUrl, HttpUtil.opttype,
"service2", HttpUtil.data);
result = URLDecoder.decode(result) ;
System.out.println("掉用方接收到的数据1:" + result);
控制台打印信息如下:
服务器返回的结果:
%D5%E2%B8%F6%CA%C7%D6%D0%CE%C4%C2%D2%C2%EB%B2%E2%CA%D4%B4%FA%C2%EB
掉用方接收到的数据1:这个是中文乱码测试代码
代码是这样的:
服务器端部分代码:
String str = "这个是中文乱码测试代码" ;
System.out.println("服务器返回的结果:");
System.out.println(str);
PrintWriter writer = resp.getWriter();
writer.write(str);
writer.flush();
接受端部分代码:
String result = HttpUtil.postToRest(HttpUtil.postUrl, HttpUtil.opttype,
"service2", HttpUtil.data);
System.out.println("掉用方接收到的数据1:" + result);
请求后返回数据,控制台打印如下:
服务器返回的结果:
这个是中文乱码测试代码
掉用方接收到的数据1:?????????????????
在网上找了一些也没有发现解决方法,大概意思都是说是因为tomcat使用的是gbk编码,gbk一个汉字两个字节,utf-8一个汉字三个字节,然后经过转码就会发生?乱码问题,如其中有一篇博客是这样讲的:
UTF-8中,一个汉字3个字节,GBK中一个汉字2个字节,我好像明白了什么。。
因为jetty容器默认是按照系统编码来决定容器编码,前提是没有自己修改启动编码,而公司里我台PC是windows的,好像默认GBK的,反正我对windows绯闻也挺多的,于是这里有一个问题,比如jetty接受到了一串经过UTF-8编码的汉字:
我很好
jetty收到的最原始的二进制数组是这样的:
[-26, -120, -111, -27, -66, -120, -27, -91, -67]
当然这不是最原始的,最原始的0和1,当然为了好看就算他是最原始的吧,下一步jetty要开始编码了,按照jetty的GBK编码,他按照2个字节一个汉字的格式去编码,于是出现了这样的组合:
[-26, -120] [ -111, -27] [-66, -120] [-27, -91] [-67]
前面每两个字节都能找到对应的汉字,最后jetty发现最后居然只有一个字节,找不到对应的汉字,心里想这SB是哪来的,于是jetty放弃它了,把它赶出去,把63丢过去,于是最后的组合成了:
[-26, -120] [ -111, -27] [-66, -120] [-27, -91] [63]
经过GBK的格式编码,两个字节对应一个汉字,就显示出了这样的东西:
骞茶帿瀛?
会出现5个,因为每2个字节代表一个汉字,最后一个字节是63,对应的符号是?,就出现了上面的东西,于是我对它做了强制的UTF-8编码,导致上面的二进制数组重新组合,经过UTF-8的组合之后,二进制数组成了这样:
[-26, -120, -111] [-27, -66, -120] [-27, -91, 63]
再经过UTF-8显示之后,变成了这样:
我很�?
前6个字节能够正常的显示出汉字,因为那就是真正的数据,然而最后3个字节,已经被GBK处理了,替换过了,即使使用UTF-8也无法还原它原来的容貌,于是它就显示成了上面的样子,但是为什么偶数不会出错?
因为偶数能够被GBK正常的解码,也就是如果汉字是偶数,UTF-8和GBK是等同的,但是如果是奇数,则就出问题了,这也是传说中的最后一个汉字乱码的问题,因为最后一个 字节始终是63,要解决这个问题,必须要治标还要治本,项目中必须全程保证编码一致性。
文章摘自:http://www.cnblogs.com/gudi/p/4086183.html
折腾了好一会时间,忽然想到以前使用的是
java.net.URLEncoder
就是说服务器端在返回带有中文数据的时候,将字符串使用URLEncoder.encode(str)加码,
然后在调用接口端,接收到数据
java.net.URLDecoder
也就是URLDecoder.decode(str)技术解码,这样就可以完美的解决问题了。
具体代码如下:
服务器端部分返回代码:
String str= "这个是中文乱码测试代码" ;
str = URLEncoder.encode(str);
System.out.println("服务器返回的结果:");
System.out.println(str);
PrintWriter writer = resp.getWriter();
writer.write(str);
writer.flush();
调用端部分代码:
String result = HttpUtil.postToRest(HttpUtil.postUrl, HttpUtil.opttype,
"service2", HttpUtil.data);
result = URLDecoder.decode(result) ;
System.out.println("掉用方接收到的数据1:" + result);
控制台打印信息如下:
服务器返回的结果:
%D5%E2%B8%F6%CA%C7%D6%D0%CE%C4%C2%D2%C2%EB%B2%E2%CA%D4%B4%FA%C2%EB
掉用方接收到的数据1:这个是中文乱码测试代码
相关文章推荐
- 使用http请求,中文乱码问题--解决方法
- 对于使用了SSH造成的中文乱码问题,4大解决方法
- 使用CInternetSession获取utf-8页面中文乱码问题解决方法
- mysql使用source 命令后表内中文乱码问题的解决方法
- 使用CInternetSession获取utf-8页面中文乱码问题解决方法
- 对于使用了SSH造成的中文乱码问题,4大解决方法
- VC轻松解析XML文件--CMarkup使用方法(解决解析中文字符出现乱码问题)
- jsp中使用传参时出现中文乱码问题的解决方法
- php使用GD图像库绘制输出图像出现乱码问题和图片上输出中文出现乱码问题解决方法。
- spring boot使用i18n时properties文件中文乱码问题的解决方法
- VC轻松解析XML文件--CMarkup使用方法(解决解析中文字符出现乱码问题)
- PHP使用strrev翻转中文乱码问题的解决方法
- win7 64位系统使用VS2010生成时出现中文目录乱码问题的解决方法【转】
- httpClient使用postMethod方法发送请求,携带参数并解决中文乱码问题
- PHP中使用file_get_contents抓取网页中文乱码问题解决方法
- QT 5.9版本 使用MSVC2015编译时出现中文字符乱码问题的解决方法
- ajax post请求中文乱码问题解决(不使用escape方法,只使用filter)
- ASP.NET Core2.0 使用VSCode 版本1.13.1工具 开发控制台运行出现中文乱码问题及解决方法
- Oracle客户端使用sqlldr导数据中文乱码问题解决方法
- mysql导入导出数据中文乱码解决方法小结(1、navicat导入问题已解决,创建连接后修改连接属性,选择高级->将使用Mysql字符集复选框去掉,下拉框选择GBK->导入sql文件OK;2、phpmyadmin显示乱码的问题也解决,两步:1.将sql文件以utf8的字符集编码另存,2.将文件中sql语句中的字段字符集编码改成utf8,导入OK)