J'utilise Volley pour mon Android) pour récupérer les données de mon serveur. Cela fonctionne bien, sauf lorsque l'erreur est traitée sur mon serveur. Mon serveur envoie cette réponse lorsqu'il est une erreur:
{
"status": 400,
"message": "Errors (2): A name is required- Julien is already used. Not creating."
}
Mon but est d’obtenir le message puis de l’afficher dans un Toast
. J'ai suivi quelques exemples pour savoir comment faire cela, mais cela ne fonctionne pas.
Il y a mon écouteur d'erreur:
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();
}
Et là le résultat de mon débogueur: testerror ﹕ 400 [B @ 430b8d60
EDIT: De plus mon error.getMessage () est null.
Je ne comprends donc pas pourquoi ma variable response.data n'est pas la réponse de mon serveur.
Si quelqu'un sait comment je peux obtenir le message de mon serveur, ce sera cool.
Merci,
J'ai mis en place quelque chose de similaire à cela, et c'est relativement simple. Votre message de journal imprime ce qui ressemble à du charabia, car response.data
Est vraiment un tableau d'octets - pas un String
. De plus, un VolleyError
n'est en réalité qu'un Exception
étendu, donc Exception . GetMessage () ne renverra probablement pas ce que vous recherchez, sauf si vous écrasez les méthodes d'analyse pour analyser votre VolleyError
dans votre classe étendue Request
. Un moyen très simple de gérer cela serait de faire quelque chose comme:
//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;
}
}
Si vous ajoutez ceci à vos classes Request
étendues, votre getMessage()
ne devrait au moins pas renvoyer null. Normalement, cela ne me dérange pas vraiment, car il est assez facile de tout faire à partir de votre méthode onErrorResponse(VolleyError e)
.
Vous devriez utiliser une bibliothèque JSON pour simplifier les choses - j'utilise Gson par exemple, ou vous pouvez utiliser JSONObject
s d'Apache, qui ne devrait pas nécessiter une bibliothèque externe supplémentaire. La première étape consiste à obtenir la réponse JSON envoyée par votre serveur sous forme de String
(de la même manière que ce que je viens de démontrer). Ensuite, vous pouvez éventuellement la convertir en JSONObject ( en utilisant JSONObject
s et JsonArray
s d'Apache, ou une autre bibliothèque de votre choix) ou simplement analysez vous-même le String
. Après cela, il vous suffit d’afficher le Toast
.
Voici un exemple de code pour vous aider à démarrer:
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();
}
essayez cette classe pour gérer toutes les erreurs
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);
}