Android:如何使用Volley处理来自服务器的消息错误?

时间:2014-02-18 23:39:00

标签: android android-volley

我使用 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

编辑:此外我的error.getMessage()为空。

所以我不明白为什么我的变量response.data不是来自我服务器的响应。

如果有人知道如何从我的服务器收到消息,那将很酷。

THX,

2 个答案:

答案 0 :(得分:154)

我已经实现了类似的东西,而且相对简单。您的日志消息打印出看似乱码的内容,因为response.data实际上是一个字节数组 - 而不是String。此外,VolleyError实际上只是一个扩展的Exception,因此Exception。getMessage()可能不会返回您要查找的内容,除非您重写解析方法以解析您的{{ 1}}在扩展的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至少应该不返回null。不过,我通常不会为此烦恼,因为从getMessage()方法中完成所有操作都很容易。

您应该使用JSON库来简化操作 - 例如我使用Gson,或者您可以使用不需要额外外部库的Apache onErrorResponse(VolleyError e)。第一步是将从服务器发送的响应JSON作为JSONObject(以与我刚才演示的方式类似的方式),然后您可以选择将其转换为JSONObject(使用apache的{ {1}} s和String s,或您选择的其他库)或者只是自己解析JSONObject。之后,您只需显示JsonArray

以下是一些示例代码,可帮助您入门:

String

答案 1 :(得分:6)

尝试此类来处理所有错误

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);
        }