Reputation: 9190
I'm trying to make a POST
request to my API and it works in Postman
(I get a valid JSON object), but not using Volley
. With the following 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;
}
});
I get the following error:
02-12 21:42:54.774: E/Volley(19215): [46574] BasicNetwork.performRequest: Unexpected response code 400 for http://somename/token/
I have seen a lot of examples and I don't really see what is going wrong here. Anyone any idea?
I updated the code with this method:
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;
}
and changed getHeaders()
to:
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return createBasicAuthHeader("username", "password");
}
Still getting the same error!
Upvotes: 22
Views: 47534
Reputation: 714
If you are passing the json value to in body(raw json).No need to set the content type as headers.put("Content-Type", "application/json; charset=utf-8");
When I was using the content type in header callback ,the 400 response status I was getting in logcat.I commented headers.put("Content-Type", "application/json; charset=utf-8"); as because I am passing raw json in body while calling api.screenshot for postman is attached.It will help
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<String, 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
Upvotes: 9
Reputation: 516
There can be multiple reasons for this error.
One reason, of course, as said by others, is that maybe you are missing or have improperly set 'Content-type' header.
If you have properly implemented that, another possible reason is that you are sending params directly from your URL. There may be a case when params is a string with some white spaces in it. These white spaces cause problems in GET requests through Volley. You need to find another way around it. That's all.
Upvotes: 6
Reputation: 812
Somertimes this error 400 is arise due to Request type so you need to change the Request.Method.GET
to Request.Method.POST
and than it works like a charm.
Upvotes: 0
Reputation: 19
I have find a solution if you are using postman for hitting the api and your api have defined serializer field like skill = serializers.JSONField() then that type of error occurred-
Solution For POSTMAN- you just add binary=True inside JSONField ex- skill = serializers.JSONField(binary=True)
Solution for Android or other client then- you just remove binary=True inside JSONField ex- skill = serializers.JSONField()
Upvotes: 0
Reputation: 234
400 error is because Content-Type is set wrong. Please do the following.
GetHeader function should be as
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> param = new HashMap<String, String>();
return param;
}
Add this new override function.
@Override
public String getBodyContentType() {
return "application/json";
}
Upvotes: 4
Reputation: 1105
In Android 2.3 there is a problem using Base64.encodeToString() as it introduces a new line in HTTP header. See my response to this question here in SO.
Short answer: Don't use Base64.encodeToString() but put the already encoded String there.
Upvotes: 0
Reputation:
I had the same problem and i removed from the header:
headers.put("Content-Type", "application/json");
now it works great!
Upvotes: 23
Reputation: 3215
I've got this error and now Iit's been fixed. I did what is told in this link. What you need to do is
if (statusCode < 200 || statusCode > 299) {
throw new IOException();
}
with
if (statusCode < 200 || statusCode > 405) {
throw new IOException();
}
Hope this helps.
Upvotes: 1
Reputation: 1672
I have the same issue before and I got the solution in my project:
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);
In the code Snippet above I used Post Method:
My answer is base on my experience and so take note:
1.) When using POST method use "StringRequest" instead of "JsonObjectRequest"
2.) inside getHeaders Override the value with an 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;
}
And everything works in my case.
Upvotes: 1
Reputation: 1858
I have removed this params.put("Content-Type", "application/x-www-form-urlencoded");
This is my Code Change.
@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;
}
Upvotes: 0
Reputation: 957
Check if you are using correct SDK
For Android Studio / IntelliJIDEA:
File -> Project Structure -> Project -> Project SDK
Modules -> Check each modules "Module SDK"
Preferably, you should use "Google API (x.x)" instead of Android API
Upvotes: -1
Reputation: 449
400 indicates a bad request, maybe you're missing Content-Type=application/json
on your headers
Upvotes: 3