webentwicklung-frage-antwort-db.com.de

Android: Wie gehe ich mit Volley mit Nachrichtenfehlern vom Server um?

Ich benutze Volley für meine Android App zum Abrufen von Daten von meinem Server. Es funktioniert gut, außer wenn der Fehler von meinem Server behandelt wird. Mein Server sendet diese Antwort, wenn er da ist ist ein Fehler:

{
    "status": 400,
    "message": "Errors (2): A name is required- Julien is already used. Not creating."
}

Mein Ziel ist es, die Nachricht zu erhalten und sie dann in einem Toast anzuzeigen. Ich habe einige Beispiele dazu verfolgt, aber es funktioniert nicht.

Da ist mein Fehlerlistener:

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

        }

nd dort das Ergebnis meines Debuggers: testerror ﹕ 400 [B @ 430b8d60

EDIT: Außerdem ist meine error.getMessage () null.

Daher verstehe ich nicht, warum meine Variable response.data nicht die Antwort von meinem Server ist.

Wenn jemand weiß, wie ich die Nachricht von meinem Server erhalten kann, ist es cool.

Danke,

70
FlavienBert

Ich habe etwas Ähnliches implementiert, und es ist relativ einfach. Ihre Protokollnachricht druckt etwas aus, das wie Kauderwelsch aussieht, da response.data Wirklich ein Byte-Array ist - kein String. Außerdem ist ein VolleyError nur ein erweitertes Exception, sodass Ausnahme . GetMessage () wahrscheinlich nicht das zurückgeben würde, wonach Sie suchen, es sei denn, Sie überschreiben die Analysemethoden zum Parsen Ihres VolleyError in Ihrer erweiterten Request Klasse. Eine wirklich einfache Möglichkeit, damit umzugehen, wäre, Folgendes zu tun:

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

Wenn Sie dies zu Ihren erweiterten Klassen Request hinzufügen, sollte Ihre Funktion getMessage() zumindest nicht null zurückgeben. Ich kümmere mich normalerweise nicht wirklich darum, da es einfach genug ist, alles aus Ihrer onErrorResponse(VolleyError e) -Methode heraus zu tun.

Sie sollten eine JSON-Bibliothek verwenden, um die Dinge zu vereinfachen - ich verwende zum Beispiel Gson oder Sie könnten die JSONObjects von Apache verwenden, für die keine zusätzliche externe Bibliothek erforderlich sein sollte. Der erste Schritt besteht darin, die von Ihrem Server gesendete JSON-Antwort als String abzurufen (ähnlich wie oben gezeigt). Anschließend können Sie sie optional in ein JSONObject (konvertieren. Verwenden Sie entweder Apaches JSONObjects und JsonArrays oder eine andere Bibliothek Ihrer Wahl) oder analysieren Sie einfach selbst String. Danach müssen Sie nur noch das Toast anzeigen.

Hier ist ein Beispielcode für den Einstieg:

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

versuchen Sie diese Klasse, um alle Fehler zu behandeln

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);
        }
6
Mina Fawzy