web-dev-qa-db-fra.com

Android Volley me donne 400 erreur

J'essaie de faire une demande POST à mon API et cela fonctionne dans Postman (je reçois un objet JSON valide), mais je n'utilise pas Volley. Avec le code suivant:

String URL = "http://somename/token";
RequestQueue queue = Volley.newRequestQueue(StartActivity.this);
queue.add(new JsonObjectRequest(Method.POST, URL, null,
   new Listener<JSONObject>() {
       @Override
       public void onResponse(JSONObject response) {
           // handle response
           Log.i("StartActivity", response.toString());
       }
   }, new ErrorListener() {
       @Override
       public void onErrorResponse(VolleyError error) {
           // handle error   
           Log.i("StartActivity", error.toString());
       }
   }) {

   @Override
   public Map<String, String> getHeaders() throws AuthFailureError {
       HashMap<String, String> headers = new HashMap<String, String>();
       headers.put("username", "someUsername");
       headers.put("password", "somePassword");
       headers.put("Authorization", "Basic someCodeHere");
       return headers;
   }
   @Override
    protected Map<String,String> getParams(){
        Map<String,String> params = new HashMap<String, String>();
        params.put("grant_type", "client_credentials");

            return params;
        }
   });

Je reçois l'erreur suivante:

02-12 21:42:54.774: E/Volley(19215): [46574] BasicNetwork.performRequest: Unexpected response code 400 for http://somename/token/

J'ai vu beaucoup d'exemples et je ne vois pas vraiment ce qui ne va pas ici. Quelqu'un a une idée?

J'ai mis à jour le code avec cette méthode:  

HashMap<String, String> createBasicAuthHeader(String username, String password) {
        HashMap<String, String> headerMap = new HashMap<String, String>();

        String credentials = username + ":" + password;
        String base64EncodedCredentials =
                Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
        headerMap.put("Authorization", "Basic " + base64EncodedCredentials);

        return headerMap;
    }

et changé getHeaders() en:

@Override
   public Map<String, String> getHeaders() throws AuthFailureError {
       return createBasicAuthHeader("username", "password");
   }

Toujours avoir la même erreur!

20
Loolooii

J'ai eu le même problème et j'ai retiré de l'en-tête:

  headers.put("Content-Type", "application/json");

maintenant cela fonctionne très bien!

17
user3136364

Si vous transmettez la valeur json à in body (raw json) .Pas besoin de définir le type de contenu sur headers.put ("Content-Type", "application/json; charset = utf-8");

Lorsque j'utilisais le type de contenu dans le rappel d'en-tête, l'état de réponse 400 que je recevais dans logcat.J'ai commenté headers.put ("Content-Type", "application/json; charset = utf-8"); comme parce que je passe json brut dans le corps tout en appelant api.screenshot for postman est attaché.Il aidera

private void volleyCall(String email, String password) {

      RequestQueue queue= Volley.newRequestQueue(this);
      String URL = "http://XXXX.in:8080/XXXX/api/userService/login";

      Map<String, String> jsonParams = new HashMap<S[enter image description here][1]tring, String>();
      jsonParams.put("email", email);
      jsonParams.put("password", password);
      Log.d(TAG,"Json:"+ new JSONObject(jsonParams));

      JsonObjectRequest postRequest = new JsonObjectRequest( Request.Method.POST, URL,new JSONObject(jsonParams),
              new Response.Listener<JSONObject>() {
                  @Override
                  public void onResponse(JSONObject response) {
                      Log.d(TAG,"Json"+ response);
                  }
              },
              new Response.ErrorListener() {
                  @Override
                  public void onErrorResponse(VolleyError error) {
                      //   Handle Error
                      Log.d(TAG, "Error: " + error
                              + "\nStatus Code " + error.networkResponse.statusCode
                              + "\nResponse Data " + error.networkResponse.data
                              + "\nCause " + error.getCause()
                              + "\nmessage" + error.getMessage());
                  }
              }) {
          @Override
          public Map<String, String> getHeaders() throws AuthFailureError {
              HashMap<String, String> headers = new HashMap<String,String>();
             // headers.put("Content-Type", "application/json; charset=utf-8");
              return headers;
          }
          @Override
          public String getBodyContentType() {
              return "application/json";
          }



      };

      queue.add(postRequest);

  }

LogCat:
LoginActivity: Json:{"email":"[email protected]","password":"abcde"}
LoginActivity: Error: com.Android.volley.ServerError

Status Code 400                                                                     
Response Data [B@63ca992                                                                              
Cause null                                                                              
messagenull
7
Priyanshu Singh

Il peut y avoir plusieurs raisons pour cette erreur.

Une des raisons, bien sûr, comme l'ont dit d'autres personnes, est peut-être qu'il vous manque ou que vous avez mal défini l'en-tête 'Content-type'.

Si vous avez correctement implémenté cela, une autre raison possible est que vous envoyez des paramètres directement à partir de votre URL. Il peut y avoir un cas où params est une chaîne contenant des espaces. Ces espaces constituent des problèmes dans les requêtes GET via Volley. Vous devez trouver un autre moyen de contourner le problème. C'est tout.

4
Rohit

L'erreur 400 est due au fait que Content-Type est mal défini . Veuillez procéder comme suit.

  1. La fonction GetHeader devrait être aussi 

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
    
            Map<String, String> param = new HashMap<String, String>();
    
            return param;
        }
    
  2. Ajoutez cette nouvelle fonction de substitution.

        @Override
        public String getBodyContentType() {
            return "application/json";
        }
    
4
Kashi

400 indique une mauvaise requête. Peut-être que vous manquez Content-Type=application/json dans vos en-têtes

3
Leonardo Pinto

J'ai le même problème avant et j'ai eu la solution dans mon projet:

RequestQueue requestManager = Volley.newRequestQueue(this);

        String requestURL = "http://www.mywebsite.org";
        Listener<String> jsonListerner = new Response.Listener<String>() {
            @Override
            public void onResponse(String list) {

            }
        };

        ErrorListener errorListener = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.w("Volley Error", error.getMessage());
            }
        };

        StringRequest fileRequest = new StringRequest(Request.Method.POST, requestURL, jsonListerner,errorListener){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> params = new HashMap<String, String>();
                params.put("token", account.getToken());
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                // do not add anything here
                return headers;
            }
        };
        requestManager.add(fileRequest);

Dans l'extrait de code ci-dessus, j'ai utilisé la méthode Post:

Ma réponse est basée sur mon expérience et prenez donc note: 

1.) Lorsque vous utilisez la méthode POST, utilisez "StringRequest" au lieu de "JsonObjectRequest".

2.) Inside getHeaders Remplace la valeur par un HashMap vide

 example snippet:

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String,String> params = new HashMap<String, String>();
            params.put("token", account.getToken());
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            // do not add anything here
            return headers;
        }

Et tout fonctionne dans mon cas.

1
neferpitou

J'ai cette erreur et maintenant, ça a été corrigé. J'ai fait ce qui est dit dans ce lien . Ce que tu dois faire c'est

  1. allez sur src/com/Android/volley/toolbox/BasicNetwork.Java
  2. Changer les lignes suivantes
 if (statusCode < 200 || statusCode > 299) {
     throw new IOException();
 }

avec

 if (statusCode < 200 || statusCode > 405) {
     throw new IOException();
 }

J'espère que cela t'aides.

1
stackex

Dans Android 2.3, l'utilisation de Base64.encodeToString () pose un problème car elle introduit une nouvelle ligne dans l'en-tête HTTP. Voir ma réponse à cette question ici à SO.

Réponse courte: n'utilisez pas Base64.encodeToString (), mais placez la chaîne déjà encodée.

0
Raul Pinto

J'ai trouvé une solution si vous utilisez postman pour frapper l'api et que votre api a défini un champ de sérialiseur comme skill = serializers.JSONField (), alors ce type d'erreur est survenu-

Solution Pour POSTMAN - Vous ajoutez simplement binaire = True dans JSONField ex - skill = serializers.JSONField (binary = True)  

Solution pour Android ou un autre client alors-vous venez de supprimer binaire = True dans JSONField ex- skill = serializers.JSONField ()  

0
suresh prajapati

J'ai supprimé ce paramètre ("Content-Type", "application/x-www-form-urlencoded");

Ceci est mon changement de code. 

@Override
        protected Map<String,String> getParams(){
            Map<String,String> params = new HashMap<String, String>();
            if(!isLogout) {
                params.put("username", username);
                params.put("password", password);
                params.put("grant_type", "password");
            } else {
            }
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String,String> params = new HashMap<String, String>();
            if(isLogout) {
                params.put("Authorization", "bearer "+LibraryDataModel.getToken());
            }else {
            // Removed this line
            // params.put("Content-Type", "application/x-www-form-urlencoded");
            }
            return params;
        }
0
dhiku

Parfois, cette erreur 400 est due au type de requête. Vous devez donc modifier le Request.Method.GET en Request.Method.POST et cela fonctionne comme un charme.

0
Dhruv Tyagi