Android: Как обрабатывать сообщение об ошибке с сервера с помощью Volley?
Я использую волейбол для моего приложения для Android, чтобы получить данные с моего сервера. Он работает хорошо, за исключением обработки ошибки с моего сервера. Мой сервер отправляет этот ответ, когда есть ошибка:
{
"status": 400,
"message": "Errors (2): A name is required- Julien is already used. Not creating."
}
моя цель-получить сообщение, а затем отобразить его в Toast. Я следовал за некоторым образцом, как это сделать, но это не работает.
есть моя ошибка слушателя:
public void onErrorResponse(VolleyError error) {
int statusCode = error.networkResponse.statusCode;
NetworkResponse response = error.networkResponse;
Log.d("testerror",""+statusCode+" "+response.data);
// Handle your error types accordingly.For Timeout & No connection error, you can show 'retry' button.
// For AuthFailure, you can re login with user credentials.
// For ClientError, 400 & 401, Errors happening on client side when sending api request.
// In this case you can check how client is forming the api and debug accordingly.
// For ServerError 5xx, you can do retry or handle accordingly.
if( error instanceof NetworkError) {
} else if( error instanceof ClientError) {
} else if( error instanceof ServerError) {
} else if( error instanceof AuthFailureError) {
} else if( error instanceof ParseError) {
} else if( error instanceof NoConnectionError) {
} else if( error instanceof TimeoutError) {
}
showProgress(false);
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
и там результат моего отладчик : testerror﹕ 400 [B@430b8d60
EDIT: более того моя ошибка.getMessage () имеет значение null.
поэтому я не понимаю, почему мой переменный ответ.данные не ответ от моего сервера.
Если кто-то знает, как я могу получить сообщение с моего сервера, это будет круто.
Thx,
2 ответов:
я реализовал нечто подобное этому, и это относительно просто. Ваше сообщение журнала печатает то, что выглядит как тарабарщина, потому что
response.data- это действительно массив байтов - неString. Кроме того,VolleyErrorэто действительно лишь затянувшийсяException, так что исключение.getMessage () скорее всего не вернет то, что вы ищете, если вы не переопределите методы разбора для разбора вашегоVolleyErrorв расширенномRequestкласса. Очень простой способ справиться с этим будет делать что-то вроде://In your extended request class @Override protected VolleyError parseNetworkError(VolleyError volleyError){ if(volleyError.networkResponse != null && volleyError.networkResponse.data != null){ VolleyError error = new VolleyError(new String(volleyError.networkResponse.data)); volleyError = error; } return volleyError; } }если вы добавите это в свой расширенный
Requestклассов,getMessage()должны, по крайней мере, не возвращать null. Я обычно не очень беспокоюсь об этом, хотя, так как это достаточно легко сделать все это изнутри вашегоonErrorResponse(VolleyError e)метод.вы должны использовать библиотеку JSON для упрощения вещей - я использую Gson например, или вы можете использовать Apache
JSONObjects, которые не должны требовать дополнительной внешней библиотеки. Первый шаг состоит в том, чтобы получить ответ JSON отправляется с вашего сервера какString(аналогично тому, что я только что продемонстрировал), далее вы можете дополнительно преобразовать его в JSONObject (используя либо apacheJSONObjects иJsonArrays, или другая библиотека по вашему выбору) или просто разобратьStringсебя. После этого вам просто нужно отобразитьToast.вот пример кода, чтобы вы начали:
public void onErrorResponse(VolleyError error) { String json = null; NetworkResponse response = error.networkResponse; if(response != null && response.data != null){ switch(response.statusCode){ case 400: json = new String(response.data); json = trimMessage(json, "message"); if(json != null) displayMessage(json); break; } //Additional cases } } public String trimMessage(String json, String key){ String trimmedString = null; try{ JSONObject obj = new JSONObject(json); trimmedString = obj.getString(key); } catch(JSONException e){ e.printStackTrace(); return null; } return trimmedString; } //Somewhere that has access to a context public void displayMessage(String toastString){ Toast.makeText(context, toastString, Toast.LENGTH_LONG).show(); }
попробуйте этот класс для обработки всех erros
public class VolleyErrorHelper { /** * Returns appropriate message which is to be displayed to the user * against the specified error object. * * @param error * @param context * @return */ public static String getMessage (Object error , Context context){ if(error instanceof TimeoutError){ return context.getResources().getString(R.string.timeout); }else if (isServerProblem(error)){ return handleServerError(error ,context); }else if(isNetworkProblem(error)){ return context.getResources().getString(R.string.nointernet); } return context.getResources().getString(R.string.generic_error); } private static String handleServerError(Object error, Context context) { VolleyError er = (VolleyError)error; NetworkResponse response = er.networkResponse; if(response != null){ switch (response.statusCode){ case 404: case 422: case 401: try { // server might return error like this { "error": "Some error occured" } // Use "Gson" to parse the result HashMap<String, String> result = new Gson().fromJson(new String(response.data), new TypeToken<Map<String, String>>() { }.getType()); if (result != null && result.containsKey("error")) { return result.get("error"); } } catch (Exception e) { e.printStackTrace(); } // invalid request return ((VolleyError) error).getMessage(); default: return context.getResources().getString(R.string.timeout); } } return context.getResources().getString(R.string.generic_error); } private static boolean isServerProblem(Object error) { return (error instanceof ServerError || error instanceof AuthFailureError); } private static boolean isNetworkProblem (Object error){ return (error instanceof NetworkError || error instanceof NoConnectionError); }
Comments