Я работаю над Android-приложением и получаю JsonObject / JsonArray с сервера. Преобразование строки в Json вручную работает нормально.
Недавно я переключился на Volley для запросов сервера и хочу использовать JsonObjectRequest
/ JsonArrayRequest
(а не просто StringRequest), чтобы напрямую получить json и не нужно беспокоиться о преобразовании первой строки (для чего были сделаны запросы Json, не так ли? ). Тем не менее, код всегда заканчивается в onErrorResponse
с ParseError, говорящим, что String cannot be converted to a JsonObject / JsonArray
(хотя синтаксис кажется полностью нормальным). Я попытался устранить потенциальные «невидимые» символы, преобразовывая ответ сервера на UTF8 (как предлагается здесь ), но, похоже, также не решает проблему. Кроме того, версия iOS, похоже, не имеет проблем с теми же ответами (я знаю, что алгоритм синтаксического анализа может быть совсем другим).
Разумеется, работа с StringRequests
или выполнение пользовательских запросов будет выполнять эту работу (как это предлагается в нескольких других обсуждениях с использованием stackoverflow), но это просто меня сильно задевает, что я не могу заставить Json Requests работать. У кого-то была эта проблема? Было бы здорово услышать о потенциальных причинах и решениях!
Хорошо, я нашел ответ. 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); } }