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,

683   2  

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 (используя либо apache JSONObjects и 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

    Ничего не найдено.