近期在项目中使用Volley做为网络通讯框架,却发如今传输中文时会出现乱码。先交代一下项目的软硬件的基础设施 线上: Django+restful_framework+monogdb APP: Android + volleyjava
在使用android端测试以前,我使用了chrome中的Postman这款插件进行了测试,发现,中文读取是正常的。说明服务器返回的是UTF-8字符编码的数据。 可是为何在Android端会出现乱码的现象呢。 我在想是否是本地端的字符编码出了问题? 我就是用String类的转码功能,发现不起做用。 束手无策。 我去网上搜索了一下,大部分都是volley默认采用的是UTF8的字符编码格式。但是服务器返回来的UTF-8的字符串为何就是显示乱码呢。 接着我就想到了查看volley的源代码。 我发现volley的整个框架的结构是这个样子的,首先Android端构造不一样类型的request对象,总得来讲有这几大类:android
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),是怎么获取字符集的。我猜测里面确定包含了默认的字符集的定义。 打开代码:chrome
/** * 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这个框架但是要用在网络通讯的环境中的。 吐槽也没有用,咱们来看一下如何来解决中文乱码的问题。有如下几种解决方式:json