2017-03-19 49 views
1

我正在開發一個Android應用程序並從服務器獲取JsonObject/JsonArray。手動將字符串轉換爲Json可以正常工作。
我最近切換到Volley的服務器請求,並希望使用JsonObjectRequest/JsonArrayRequest(而不是簡單的StringRequest)來直接獲取json,而不必麻煩先轉換字符串(這就是Json請求的作用,對?)。 但是,代碼始終以onErrorResponse結尾,ParseError聲稱String cannot be converted to a JsonObject/JsonArray(即使語法看起來完全正常)。 我試圖通過將服務器響應轉換爲UTF8來消除潛在的「不可見」字符(建議爲here),但似乎也無法解決問題。此外,iOS版本似乎沒有任何問題與相同的響應(我知道底層的解析算法可能會非常不同)。Volley Json請求不工作 - 字符串不能轉換爲JsonObject/JsonArray

當然,使用StringRequests或自定義請求可以完成這項工作(正如其他一些stackoverflow討論中所建議的那樣),但是它讓我感到很困惑,因爲我無法讓Json請求工作。任何人都有這個問題呢?聽說潛在的原因和解決方案會很棒!

回答

1

好的,我找到了答案。 JsonObjectRequest/JsonArrayRequest以額外的JsonObject/JsonArray對象作爲參數。在大多數在線示例代碼中,這個參數設置爲null,並且我做了同樣的事情,因爲我不想發送Json,只能接收。 現在Volley Json請求的幕後發生了什麼(相當不直觀),是如果此參數爲null,則請求不會作爲POST請求完成,而是作爲GET取代。這導致我的請求失敗,服務器返回錯誤代碼而不是JSON。反過來,這樣的錯誤代碼無法解析爲json。 我在Volley中找到一個默認實現的非常糟糕的選擇。

在任何情況下,該解決方案是作爲引入CustomJsonObjectRequest這非常類似於從庫中實施,不同之處在於它與POST請求棒容易:

public class CustomJsonObjectRequest extends Request<JSONObject> { 

protected static final String PROTOCOL_CHARSET = "utf-8"; 

private final Response.Listener<JSONObject> mListener; 

public CustomJsonObjectRequest(String url, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { 
    super(Method.POST, url, errorListener); 
    mListener = listener; 
} 

@Override 
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String jsonString = new String(response.data, 
       HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET)); 
     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)); 
    } 
    } 

    @Override 
    protected void deliverResponse(JSONObject response) { 
    mListener.onResponse(response); 
    } 

}