文档章节

Android Volley 框架JSON中文乱码问题的解决

troy_psl
 troy_psl
发布于 2015/03/31 10:53
字数 1067
阅读 7112
收藏 49

近期在项目中使用Volley作为网络通信框架,却发现在传输中文时会出现乱码。先交代一下项目的软硬件的基础设施 线上: Django+restful_framework+monogdb APP: Android + volley

在使用android端测试之前,我使用了chrome中的Postman这款插件进行了测试,发现,中文读取是正常的。说明服务器返回的是UTF-8字符编码的数据。 但是为什么在Android端会出现乱码的现象呢。 我在想是不是本地端的字符编码出了问题? 我就是用String类的转码功能,发现不起作用。 一筹莫展。 我去网上搜索了一下,大部分都是volley默认采用的是UTF8的字符编码格式。可是服务器返回来的UTF-8的字符串为什么就是显示乱码呢。 接着我就想到了查看volley的源代码。 我发现volley的整个框架的结构是这个样子的,首先Android端构造不同类型的request对象,总得来说有这几大类:

  • JSONObjectRequest
  • JSONArrayRequest
  • StringRequest 它们都有一个共同的基类——Reuqest。所有继承Request的子类都必须覆盖以下两个方法:
  • protected Response<T> parseNetworkResponse(NetworkResponse response);
  • protected void deliverResponse(T response); 第一个方法是用来解析服务器返回的原始数据。response对象包含了返回数据的body、headers等内容,需要在该方法中对返回数据进行解析。比如JSONObjectRequest就是使用response中的body字符串 构造一个JSONObject对象,传递给监听器的对象。这样的设计默认了消息的发送者必将知道服务器的返回是如何解析的这一潜规则。 接着,我就查看了一下JSONOBjectReuqest类中的parseNetworkResponse方法,看看它在将结果传递给监听器之前做了什么。 源代码如下:
   @Override
   protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
       try {
           String jsonString =
               new String(response.data, HttpHeaderParser.parseCharset(response.headers));
           return Response.success(new JSONObject(jsonString),
                   HttpHeaderParser.parseCacheHeaders(response));
       } catch (UnsupportedEncodingException e) {
           return Response.error(new ParseError(e));
       } catch (JSONException je) {
           return Response.error(new ParseError(je));
       }
   }

我们看到了,JSONObjectRequest这个类在将数据返回给监听器之前,是对字符串进行了转码的。我们貌似接近了问题的本质。那就接着查看HttpHeaderParser.parseCacheHeaders(response),是怎么获取字符集的。我猜想里面肯定包含了默认的字符集的定义。 打开代码:

  /**
   * Returns the charset specified in the Content-Type of this header,
   * or the HTTP default (ISO-8859-1) if none can be found.
   */
  public static String parseCharset(Map<String, String> headers) {
      String contentType = headers.get(HTTP.CONTENT_TYPE);
      if (contentType != null) {
          String[] params = contentType.split(";");
          for (int i = 1; i < params.length; i++) {
              String[] pair = params[i].trim().split("=");
              if (pair.length == 2) {
                  if (pair[0].equals("charset")) {
                      return pair[1];
                  }
              }
          }
      }
      return HTTP.DEFAULT_CONTENT_CHARSET;
  }

看到了注释,一切都水落石出了,原来,如果在服务器的返回数据的header中没有指定字符集那么就会默认使用 ISO-8859-1 字符集。 ISO-8859-1的别名叫做Latin1。这个字符集支持部分是用于欧洲的语言,不支持中文~ 很不能理解为什么将这个字符集作为默认的字符集。Volley这个框架可是要用在网络通信的环境中的。 吐槽也没有用,我们来看一下如何来解决中文乱码的问题。有以下几种解决方式:

  1. 在服务器的返回的数据的header的中contentType加上charset=UTF-8的声明。
  2. 当你无法修改服务器程序的时候,可以定义一个新的子类。覆盖parseNetworkResponse这个方法,直接使用UTF-8对服务器的返回数据进行转码。 好的,写完了。 我们总结一下,从这个问题的解决中,我们能够获取以下的经验: 1.网上的信息不能够全信,要相信自己的判断。 2.看源代码很重要,一般通过源代码找问题解决的办法是最快的。比在网上漫无目的的搜索要来的高效。

© 著作权归作者所有

troy_psl
粉丝 1
博文 1
码字总数 1067
作品 0
南京
程序员
私信 提问
加载中

评论(8)

相公无爱
相公无爱
http://www.weather.com.cn/data/sk/101010100.html这个你们可以吗?
b
bololi

引用来自“王武娟”的评论

可以使用String s =new String(response.getBytes("ISO-8859-1"),"utf-8");这个方法转换,一切正常
这个办法好,多谢!81
王武娟
可以使用String s =new String(response.getBytes("ISO-8859-1"),"utf-8");这个方法转换,一切正常
O
OMOM
添加了UTF-8还是乱码,郁闷啊
troy_psl
troy_psl 博主

引用来自“weimoliang”的评论

凑巧,前两天,也发现这个问题了,还没来得及解决!哈哈哈~~~
看来这个问题遇到的忍还挺多的啊
weimoliang
weimoliang
凑巧,前两天,也发现这个问题了,还没来得及解决!哈哈哈~~~
troy_psl
troy_psl 博主

引用来自“Max-Xu”的评论

我今天也恰好发现这个问题,正准备写一下的,哈哈81
哈哈,好巧啊
xBinary
xBinary
我今天也恰好发现这个问题,正准备写一下的,哈哈81
Android http中文乱码问题

总结下android下的中文乱码问题,以后开发东西基本就在这里写了。一是通过javaeye能认识不少朋友。二是对自己的博客内容进行管理。三是平时日志在sina的博客里写吧。 一 url to android JAV...

xiahuawuyu
2012/10/11
1K
0
Cocos移植到Android的一些问题-中文乱码问题

Android平台版本和设备碎片化很严重,因此从Win32平台移植到Android平台会有很多问题,下面是我们归纳的从Win32平台移植到Android平台遇到的一些问题。 在Android平台中文乱码并不是一个问题...

智捷课堂
2014/11/16
88
0
KJFrameForAndroid 2.20 发布,Android 应用开发框架

KJFrameForAndroid的设计思想是通过封装Android原生SDK中复杂的复杂操作而达到简化Android应用级开发,最终实现快速而又安全高效的开发APP。目标是用最少的代码,完成最多的操作,用最高的效...

kymjs张涛
2015/04/21
3.8K
21
android 向服务端发送请求编码问题

今天开发客户端时发送请求遇到了问题,经过一下午的时间终于解决(其实一句话就可以)。如果哪位朋友也遇到这样问题可以看下面的解决方法。 客户端:android 2.2 服务端:asp.net 遇到问题:...

壹尘子
2012/02/08
1K
1
cmd命令行中logcat输出日志中文乱码

http://www.6san.com/913/ 在命令行使用adb logcat命令直接输出日志中文内容显示乱码,原因是中文系统中cmd命令行窗口默认的编码是GBK,而LogCat打印的日志是UTF-8编码,所以adb logcat命令输...

塔塔米
2014/01/30
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

自定义ApiBoot Logging链路以及单元ID生成策略

ApiBoot Logging会为每一个请求都对应创建链路编号(TraceID)以及单元编号(SpanID),用于归类每一次请求日志,通过一个链路下日志单元的Parent SpanID可以进行上下级关系的梳理。 前文回顾...

恒宇少年
21分钟前
8
0
浅谈 Application 和 activity

对于 在 Application初始化一些变量,为什么不可以放在activity 或者其他的组件里呢? 这里就根据个人的理解来讲述一下,欢迎补充指正。 首先 activity 是以栈的形式出现,一个app应用会有多...

MrLins
21分钟前
8
0
Allegro的脚本文件内容里都有哪些

小伙伴们在使用Allegro的时候是否经常用到脚本文件夹呢?scr的用法其实可真不简单。。。 首先脚本文件的运行模式就存在很多种,比如不提示错误信息,不弹出确认对画框(这样很有利于我们执行...

demyar
23分钟前
16
0
微信升级外链管理规范,「砍一刀帮我加速」要被禁止了

原创: 蒋鸿昌 首发:「知晓程序」公众号 - 最好的微信新商业媒体 几天前,知名互联网评论人阑夕模仿皮尤研究中心(Pew Research Center)在美国做的互联网通识调查问卷,做了一份中文版问卷...

知晓云
23分钟前
14
0
CentOS 7接投影仪

我将一台安装着CentOS 7图形界面的惠普笔记本电脑当桌面使用。最近,想要连接投影仪时却遇到了问题。笔记本有一个HDMI接口。我买了一个HDMI---->VGA的转接线,连上笔记本电脑后,屏幕一直在闪...

大别阿郎
27分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部