Android Volley 框架JSON中文亂碼問題的解決

近期在項目中使用Volley做爲網絡通訊框架,卻發如今傳輸中文時會出現亂碼。先交代一下項目的軟硬件的基礎設施 線上: Django+restful_framework+monogdb APP: Android + volleyjava

在使用android端測試以前,我使用了chrome中的Postman這款插件進行了測試,發現,中文讀取是正常的。說明服務器返回的是UTF-8字符編碼的數據。 可是爲何在Android端會出現亂碼的現象呢。 我在想是否是本地端的字符編碼出了問題? 我就是用String類的轉碼功能,發現不起做用。 束手無策。 我去網上搜索了一下,大部分都是volley默認採用的是UTF8的字符編碼格式。但是服務器返回來的UTF-8的字符串爲何就是顯示亂碼呢。 接着我就想到了查看volley的源代碼。 我發現volley的整個框架的結構是這個樣子的,首先Android端構造不一樣類型的request對象,總得來講有這幾大類:android

  • 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),是怎麼獲取字符集的。我猜測裏面確定包含了默認的字符集的定義。 打開代碼: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

  1. 在服務器的返回的數據的header的中contentType加上charset=UTF-8的聲明。
  2. 當你沒法修改服務器程序的時候,能夠定義一個新的子類。覆蓋parseNetworkResponse這個方法,直接使用UTF-8對服務器的返回數據進行轉碼。 好的,寫完了。 咱們總結一下,從這個問題的解決中,咱們可以獲取如下的經驗: 1.網上的信息不可以全信,要相信本身的判斷。 2.看源代碼很重要,通常經過源代碼找問題解決的辦法是最快的。比在網上漫無目的的搜索要來的高效。
相關文章
相關標籤/搜索