web-dev-qa-db-ja.com

Android Volleyは私に400エラーを与えます

APIにPOSTリクエストを作成しようとしていますが、Postman(有効なJSONオブジェクトを取得)で機能しますが、Volleyは使用しません。次のコードで:

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

次のエラーが表示されます。

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

私は多くの例を見てきましたが、ここで何が間違っているのか本当にわかりません。誰でもアイデアはありますか?

このメソッドでコードを更新しました:

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

getHeaders()を次のように変更しました:

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

それでも同じエラーが発生します!

21
Loolooii

私は同じ問題を抱えていて、ヘッダーから削除しました:

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

今ではうまくいきます!

18
user3136364

Body(raw json)にjson値を渡す場合。コンテンツタイプをheaders.put( "Content-Type"、 "application/json; charset = utf-8");として設定する必要はありません。

ヘッダーコールバックでコンテンツタイプを使用していたとき、logcatで取得していた400応答ステータス。headers.put( "Content-Type"、 "application/json; charset = utf-8");とコメントしました。なぜなら、郵便配達員のapi.screenshotを呼び出している間に生のjsonを本文に渡すからです。

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
8
Priyanshu Singh

このエラーには複数の理由があります。

もちろん、他の人が言ったように、理由の1つは、「Content-type」ヘッダーが見つからないか、不適切に設定されている可能性があることです。

適切に実装している場合、考えられるもう1つの理由は、URLから直接パラメーターを送信していることです。 paramsが空白を含む文字列である場合があります。これらの空白は、Volleyを介したGET要求で問題を引き起こします。別の方法を見つける必要があります。それで全部です。

4
Rohit

400エラーは、Content-Typeの設定が間違っているためです。以下を行ってください。

  1. GetHeader関数は次のようになります

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
    
            Map<String, String> param = new HashMap<String, String>();
    
            return param;
        }
    
  2. この新しいオーバーライド関数を追加します。

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

400は不適切なリクエストを示します。おそらく、あなたはContent-Type=application/jsonヘッダーに

3
Leonardo Pinto

以前にも同じ問題があり、プロジェクトで解決策を得ました:

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

上記のコードスニペットでは、Postメソッドを使用しました。

私の答えは私の経験に基づいているので、注意してください:

1.)POSTメソッドを使用する場合、「JsonObjectRequest」の代わりに「StringRequest」を使用します

2.)getHeaders内で空の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;
        }

そして、私の場合はすべてうまくいきます。

1
neferpitou

このエラーが発生しましたが、現在は修正されています。 このリンク で説明されていることを行いました。あなたがする必要があるのは

  1. src/com/Android/volley/toolbox/BasicNetwork.Javaにアクセスします
  2. 次の行を変更します
 if (statusCode < 200 || statusCode > 299) {
     throw new IOException();
 }

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

お役に立てれば。

1
stackex

Android 2.3では、Base64.encodeToString()を使用するとHTTPヘッダーに新しい行が導入されるため、問題があります。この質問に対する私の回答 を参照してください SO.

簡単な答え:Base64.encodeToString()を使用しないで、既にエンコードされた文字列をそこに配置します。

0
Raul Pinto

あなたがAPIをヒットするために郵便配達員を使用していて、あなたのAPIがskill = serializers.JSONField()のようなシリアライザーフィールドを定義している場合、私は解決策を見つけました

POSTMAN-のソリューション JSONField内にbinary = Trueを追加するだけですex- skill = serializers.JSONField(binary = True)

Androidまたは他のクライアントのソリューション-JSONField ex内のbinary = Trueを削除するだけですskill = serializers.JSONField()

0

このparams.put( "Content-Type"、 "application/x-www-form-urlencoded");を削除しました。

これは私のコード変更です。

@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

リクエストタイプが原因でこのエラー400が発生する場合があるため、Request.Method.GETからRequest.Method.POSTそしてそれは魅力のように動作します。

0
Dhruv Tyagi