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

还有我的debugging器的结果: testerror:400 [B @ 430b8d60

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

所以我不明白为什么我的variablesresponse.data不是我的服务器的响应。

如果有人知道我怎么能从我的服务器得到消息,这将是很酷的。

谢谢,

我已经实现了类似的东西,它相对简单。 您的日志消息打印出来看起来像是乱码,因为response.data实际上是一个字节数组 – 不是String 。 此外, VolleyError实际上只是一个扩展的Exception ,因此Exception .getMessage()可能不会返回您正在查找的内容,除非您在扩展的Request类中重写parsing您的VolleyError的parsing方法。 处理这个问题的一个非常基本的方法是做类似的事情:

 //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()至less不应该返回null。 但是,我通常不会真的为此烦恼,因为从onErrorResponse(VolleyError e)方法中很容易完成所有操作。

你应该使用JSON库来简化事情 – 例如我使用Gson ,或者你可以使用Apache的JSONObject ,它不需要额外的外部库。 第一步是将服务器发送的响应JSON作为String (与我刚刚演示的方式类似),接下来可以select将其转换为JSONObject (使用apache的JSONObjectJsonArray或其他库)或者只是自己parsingString 。 之后,你只需要显示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(); } 

尝试这个类来处理所有的错误

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