Android Volley给了我400错误

时间:2014-02-12 20:50:41

标签: android rest android-volley

我正在尝试向我的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");
   }

仍然得到同样的错误!

11 个答案:

答案 0 :(得分:18)

我有同样的问题,我从标题中删除了:

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

现在它很棒!

答案 1 :(得分:8)

如果要将json值传递给body(raw json)。不需要将内容类型设置为headers.put(&#34; Content-Type&#34;,&#34; application / json; charset = UTF-8&#34);

当我在标题回调中使用内容类型时,我在logcat中获得了400响应状态。我评论了headers.put(&#34; Content-Type&#34;,&#34; application / json; charset = UTF-8&#34);因为我正在传递原始json在身体,同时调用api.screenshot为postman附加。它将帮助

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":"XXXXXX@gmail.com","password":"abcde"}
LoginActivity: Error: com.android.volley.ServerError

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

答案 2 :(得分:4)

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

答案 3 :(得分:3)

400表示错误请求,可能您在标题上遗漏了Content-Type=application/json

答案 4 :(得分:1)

之前我遇到过同样的问题,我在项目中得到了解决方案:

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 Method:

我的答案基于我的经验,所以请注意:

1。)使用POST方法时使用&#34; StringRequest&#34;而不是&#34; JsonObjectRequest&#34;

2。)getHeaders内部使用Empty 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;
        }

一切都适用于我的情况。

答案 5 :(得分:1)

我发现了这个错误,现在我已经修好了。我做了this link中所说的。你需要做的是

  1. 转到src / com / android / volley / toolbox / BasicNetwork.java
  2. 更改以下行
  3.  if (statusCode < 200 || statusCode > 299) {
         throw new IOException();
     }
    

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

    希望这有帮助。

答案 6 :(得分: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;
        }

答案 7 :(得分:0)

在Android 2.3中,使用Base64.encodeToString()时出现问题,因为它在HTTP标头中引入了一个新行。请参阅我的回复mongodb converting isodate to numerical value

简短回答:不要使用Base64.encodeToString(),而是将已编码的字符串放在那里。

答案 8 :(得分:0)

我找到了一个解决方案,如果你使用postman来命中api并且你的api已经定义了类似skill = serializers.JSONField()的序列化器字段,那么那种类型的错误发生了 -

POSTMAN解决方案 - 你只需在JSONField中添加binary = True ex- skill = serializers.JSONField(binary = True)

Android或其他客户的解决方案然后 - 你只需删除JSONField中的binary = True ex- skill = serializers.JSONField()

答案 9 :(得分:0)

有时此错误400是由于请求类型引起的,因此您需要将Request.Method.GET更改为Request.Method.POST,然后它像一个超级按钮一样起作用。

答案 10 :(得分:-1)

检查您是否使用了正确的SDK

对于Android Studio / IntelliJIDEA:

File -> Project Structure -> Project -> Project SDK 
Modules -> Check each modules "Module SDK" 

最好使用&#34; Google API(x.x)&#34;而不是Android API