OkHttp header、post參數不支持中文的解決辦法

現象

項目在接入Okhttp請求框架的時候,發現當header或post參數中包含有中文的時候,都會報一個數組

Unexpected char xx at xx in xx value: xxxapp

這種格式的錯誤,下面把緣由和解決辦法分享給你們框架

緣由

查看源碼能夠發現,不論你從什麼入口設置header 或 post參數,Okhttp都會對其進行這樣一段代碼的檢查post

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 <= '\u001f' || 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 >= '\u007f') {
            throw new IllegalArgumentException(Util.format(
                    "Unexpected char %#04x at %d in %s value: %s", (int) c, i, name, value));
        }
    }
}

而這也就使得當參數中含有中文時就會報錯ui

解決辦法

header參數

把使用 requestBuilder.header(name , value)的地方url

替換成requestBuilder.header(name , getValueEncoded(value) )code

方法代碼以下:orm

//因爲okhttp header 中的 value 不支持 null, \n 和 中文這樣的特殊字符,因此這裏
//會首先替換 \n ,而後使用 okhttp 的校驗方式,校驗不經過的話,就返回 encode 後的字符串
private static String getValueEncoded(String value) {
    if (value == null) return "null";
    String newValue = value.replace("\n", "");
    for (int i = 0, length = newValue.length(); i < length; i++) {
        char c = newValue.charAt(i);
        if (c <= '\u001f' || c >= '\u007f') {
            return URLEncoder.encode(newValue, "UTF-8");
        }
    }
    return newValue;
}

post參數

post參數能夠經過將鍵值對轉換爲byte數組的形式來避免OKhttp的字符檢查utf-8

requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"),
                getRequestData(postParams).toString().getBytes(「UTF-8」)));
                
                
private static StringBuffer getRequestData(Map<String, String> params) {
    StringBuffer stringBuffer = new StringBuffer();    
    try {
        for (Map.Entry<String, String> entry : params.entrySet()) {
            stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        stringBuffer.deleteCharAt(stringBuffer.length() - 1);    //刪除最後的一個"&"
    } catch (Exception e) {
        e.printStackTrace();
    }
    return stringBuffer;
}

另外,這裏比較重要的還有這句話:字符串

MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"

此處若是沒有charset=utf-8的話,服務端獲取中文post參數可能會出現亂碼

相關文章
相關標籤/搜索