web-dev-qa-db-de.com

Android Volley gibt mir 400 Fehler

Ich versuche, eine POST-Anforderung an meine API zu richten, und sie funktioniert in Postman (ich erhalte ein gültiges JSON-Objekt), aber Volley nicht. Mit folgendem Code:

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

Ich erhalte folgende Fehlermeldung:

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

Ich habe viele Beispiele gesehen und sehe nicht wirklich, was hier schief läuft. Hat jemand eine Idee?

Ich habe den Code mit dieser Methode aktualisiert:  

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

und getHeaders() geändert in:

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

Immer noch derselbe Fehler!

20
Loolooii

Ich hatte das gleiche Problem und entfernte mich aus dem Header:

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

jetzt klappt es super!

17
user3136364

Wenn Sie den json-Wert an body (raw json) übergeben. Sie müssen den Inhaltstyp nicht als headers.put ("Content-Type", "application/json; charset = utf-8") festlegen.

Als ich den Inhaltstyp im Header-Callback verwendete, wurde der Antwortstatus von 400 in logcat.I kommentiert. Headers.put ("Content-Type", "application/json; charset = utf-8"); als weil ich rohe json in body übergeben werde, während ich api.screenshot für den Briefträger rufe, ist beigefügt. Es wird helfen

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 [[email protected]                                                                              
Cause null                                                                              
messagenull
7
Priyanshu Singh

Für diesen Fehler kann es mehrere Gründe geben.

Ein Grund ist natürlich, wie andere sagen, dass Sie vielleicht fehlen oder den Header "Content-type" falsch gesetzt haben.

Wenn Sie dies ordnungsgemäß implementiert haben, besteht ein weiterer möglicher Grund darin, dass Sie Parameter direkt von Ihrer URL aus senden. Es kann vorkommen, dass es sich bei params um eine Zeichenfolge mit einigen Leerzeichen handelt. Diese Leerzeichen verursachen Probleme bei GET-Anforderungen durch Volley. Sie müssen einen anderen Weg finden. Das ist alles.

4
Rohit

Der Fehler 400 ist darauf zurückzuführen, dass der Inhaltstyp falsch eingestellt ist .. __ Bitte führen Sie die folgenden Schritte aus.

  1. Die GetHeader-Funktion sollte so sein 

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
    
            Map<String, String> param = new HashMap<String, String>();
    
            return param;
        }
    
  2. Fügen Sie diese neue Überschreibungsfunktion hinzu.

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

400 weist auf eine fehlerhafte Anforderung hin. Möglicherweise fehlt Ihnen Content-Type=application/json in Ihren Kopfzeilen

3
Leonardo Pinto

Ich habe das gleiche Problem schon einmal und bekam die Lösung in meinem Projekt:

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

Im obigen Code-Snippet habe ich die Post-Methode verwendet:

Meine Antwort basiert auf meinen Erfahrungen und beachte: 

1.) Bei Verwendung der Methode POST verwenden Sie "StringRequest" anstelle von "JsonObjectRequest"

2.) in getHeaders Überschreiben Sie den Wert mit einer leeren HashMap

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

Und alles funktioniert in meinem Fall.

1
neferpitou

Ich habe diesen Fehler und jetzt wurde er behoben. Ich habe getan, was in diesem Link erzählt wird. Was Sie tun müssen, ist

  1. gehe zu src/com/Android/volley/toolbox/BasicNetwork.Java
  2. Ändern Sie die folgenden Zeilen
 if (statusCode < 200 || statusCode > 299) {
     throw new IOException();
 }

mit

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

Hoffe das hilft.

1
stackex

In Android 2.3 gibt es ein Problem bei der Verwendung von Base64.encodeToString (), da eine neue Zeile im HTTP-Header eingefügt wird. Siehe meine Antwort auf diese Frage hier in SO.

Kurze Antwort: Verwenden Sie nicht Base64.encodeToString (), sondern fügen Sie den bereits codierten String dort ein.

0
Raul Pinto

Ich habe eine Lösung gefunden, wenn Sie einen Briefträger verwenden, um die API zu treffen, und Ihre API ein Serializer-Feld definiert hat, wie z. B. skill = serializers.JSONField ().

Lösung Für POSTMAN Fügen Sie einfach binary = True in JSONField hinzu. Ex- skill = serializers.JSONField (binary = True)  

Lösung für Android oder einen anderen Client. Dann entfernen Sie einfach binary = True in JSONField ex- skill = serializers.JSONField ()  

0

Ich habe dieses params.put entfernt ("Content-Type", "application/x-www-form-urlencoded");

Dies ist meine Code-Änderung. 

@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

Manchmal tritt dieser Fehler 400 aufgrund des Anfragetyps auf, daher müssen Sie den Request.Method.GET in Request.Method.POST ändern und dann funktioniert es wie ein Zauber.

0
Dhruv Tyagi