okhttp3 請(qǐng)求頭不能為中文的坑

對(duì)源碼有一定的了解,以為基本可以駕馭了,誰知道,坑來了。

問題描述:

上線接口的某一天,有用戶報(bào)障,說登錄不上,而且陸續(xù)有報(bào)障。

通過log 發(fā)現(xiàn)登錄不上,都有一個(gè)類似的報(bào)錯(cuò):
“java.lang.IllegalArgumentException: Unexpected char 0x514d at 4 in wifiSsid value: "360免費(fèi)WiFi-DP" at ”

什么?怎么和wifiSsid有關(guān)系了?后來查了一下代碼,發(fā)現(xiàn)確實(shí)在登錄接口上通過請(qǐng)求頭的形式上傳了 wifissid, 也就是連接的wifi的名字。Exception描述是第四個(gè) char ,也就是“免”字?難道是因?yàn)橹形牡脑???dāng)時(shí)是這么猜測(cè)的。

源碼查詢

猜測(cè)并不能作為判斷的標(biāo)準(zhǔn),然后做了一下測(cè)試,果然連接含義中文名字的wifi就有問題,也就是不能添加中文到請(qǐng)求頭里面。這是為什么呢?最后還是通過源碼進(jìn)行的求證:

在okhttp的源碼Header.java,發(fā)現(xiàn)set 和add header, 都會(huì)有這個(gè)判斷:

    private void checkNameAndValue(String name, String value) {
      if (name == null) throw new NullPointerException("name == null");
      if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
      for (int i = 0, length = name.length(); i < length; i++) {
        char c = name.charAt(i);
        if (c <= '\u0020' || c >= '\u007f') {
          throw new IllegalArgumentException(Util.format(
              "Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
        }
      }
      if (value == null) throw new NullPointerException("value == null");
      for (int i = 0, length = value.length(); i < length; i++) {
        char c = value.charAt(i);
        if ((c <= '\u001f' && c != '\t') || c >= '\u007f') {
          throw new IllegalArgumentException(Util.format(
              "Unexpected char %#04x at %d in %s value: %s", (int) c, i, name, value));
        }
      }
    }

嗷,No,果然是這樣,踩到深坑了。無論是header的 Key 和Value都是不能含有中文的,一旦判定為有中文的出現(xiàn),就會(huì)拋出異常,中斷請(qǐng)求。

后面想了一下,以前使用okhttp2的時(shí)候,也有上傳相同的請(qǐng)求頭,為什么就沒有這個(gè)問題呢?也同樣去查看了一下okhttp2的源碼,發(fā)現(xiàn)這個(gè)判斷是okhttp3才有的,okhttp2其實(shí)并沒有這個(gè)判斷。

解決方案:

解決方案有以下幾種:

  1. 不要傳了(當(dāng)然這個(gè)不符合需求)
  2. 把源碼這個(gè)地方改了(也不是太好,不知道會(huì)不會(huì)引起其他問題)
  3. 把中文 encode以下(相對(duì)較好的辦法):
    ssid = URLEncoder.encode(ssid);
總結(jié)

遇到問題不可怕,主要是要做好分析,及時(shí)解決,多做總結(jié),避免后門再次踩同樣的坑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容