詳解okhttp3 請(qǐng)求頭不能為中文的坑
對(duì)源碼有一定的了解,以為基本可以駕馭了,誰(shuí)知道,坑來(lái)了。
問(wèn)題描述:
上線接口的某一天,有用戶報(bào)障,說(shuō)登錄不上,而且陸續(xù)有報(bào)障。
通過(guò)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)系了?后來(lái)查了一下代碼,發(fā)現(xiàn)確實(shí)在登錄接口上通過(guò)請(qǐng)求頭的形式上傳了 wifissid, 也就是連接的wifi的名字。Exception描述是第四個(gè) char ,也就是“免”字?難道是因?yàn)橹形牡脑颍慨?dāng)時(shí)是這么猜測(cè)的。
源碼查詢
猜測(cè)并不能作為判斷的標(biāo)準(zhǔn),然后做了一下測(cè)試,果然連接含義中文名字的wifi就有問(wèn)題,也就是不能添加中文到請(qǐng)求頭里面。這是為什么呢?最后還是通過(guò)源碼進(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,果然是這樣,踩到深坑了。無(wú)論是header的 Key 和Value都是不能含有中文的,一旦判定為有中文的出現(xiàn),就會(huì)拋出異常,中斷請(qǐng)求。
后面想了一下,以前使用okhttp2的時(shí)候,也有上傳相同的請(qǐng)求頭,為什么就沒(méi)有這個(gè)問(wèn)題呢?也同樣去查看了一下okhttp2的源碼,發(fā)現(xiàn)這個(gè)判斷是okhttp3才有的,okhttp2其實(shí)并沒(méi)有這個(gè)判斷。
解決方案:
解決方案有以下幾種:
- 不要傳了(當(dāng)然這個(gè)不符合需求)
- 把源碼這個(gè)地方改了(也不是太好,不知道會(huì)不會(huì)引起其他問(wèn)題)
- 把中文 encode以下(相對(duì)較好的辦法):
ssid = URLEncoder.encode(ssid);
總結(jié)
遇到問(wèn)題不可怕,主要是要做好分析,及時(shí)解決,多做總結(jié),避免后門再次踩同樣的坑。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)屏蔽微信拉黑和刪除聯(lián)系人功能示例
本篇文章主要介紹了Android實(shí)現(xiàn)屏蔽微信拉黑和刪除聯(lián)系人功能示例,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-02-02Android開(kāi)發(fā)之保存圖片到相冊(cè)的三種方法詳解
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)的保存圖片到相冊(cè)功能的三種方法,文中的示例代碼講解詳細(xì),有一定的參考價(jià)值,感興趣的可以了解一下2022-04-04Android編程實(shí)現(xiàn)定時(shí)發(fā)短信功能示例
這篇文章主要介紹了Android編程實(shí)現(xiàn)定時(shí)發(fā)短信功能,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android定時(shí)發(fā)送短信功能的相關(guān)原理、實(shí)現(xiàn)方法與注意事項(xiàng),需要的朋友可以參考下2017-09-09Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄的代碼
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)字母導(dǎo)航欄的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09flutter 微信聊天輸入框功能實(shí)現(xiàn)
這篇文章主要介紹了flutter 微信聊天輸入框功能實(shí)現(xiàn),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Android Room數(shù)據(jù)庫(kù)多表查詢的使用實(shí)例
這篇文章主要介紹了Android Room數(shù)據(jù)庫(kù)多表查詢的使用實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Android編程自定義搜索框?qū)崿F(xiàn)方法【附demo源碼下載】
這篇文章主要介紹了Android編程自定義搜索框?qū)崿F(xiàn)方法,涉及Android界面布局、數(shù)據(jù)加載、事件響應(yīng)等相關(guān)操作技巧,并附帶完整demo源碼供讀者下載參考,需要的朋友可以參考下2017-12-12Android項(xiàng)目仿UC瀏覽器和360手機(jī)衛(wèi)士消息常駐欄(通知欄)
本篇文章主要介紹了Android項(xiàng)目仿UC瀏覽器和360手機(jī)衛(wèi)士消息常駐欄(通知欄),可以仿照360的通知欄,有興趣的可以了解一下。2016-11-11