Ответ 1
У меня была та же проблема, и я удалился из заголовка:
headers.put("Content-Type", "application/json");
теперь он отлично работает!
Я пытаюсь сделать запрос POST
к моему API и работает в 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");
}
По-прежнему получаю ту же ошибку!
У меня была та же проблема, и я удалился из заголовка:
headers.put("Content-Type", "application/json");
теперь он отлично работает!
Если вы передаете значение json в body (raw json). Не нужно устанавливать тип содержимого как headers.put( "Content-Type", "application/json; charset = utf-8" );
Когда я использовал тип контента в обратном вызове заголовка, 400-й статус ответа, который я получал в logcat.I прокомментировал headers.put( "Content-Type", "application/json; charset = utf-8" ); потому что я передаю сыну json в теле при вызове api.screenshot для почтальона. Он поможет
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
400 указывает на плохой запрос, возможно, вам не хватает Content-Type=application/json
в заголовках
400 заключается в том, что Content-Type установлен неправильно. Пожалуйста, сделайте следующее.
Функция GetHeader должна быть как
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> param = new HashMap<String, String>();
return param;
}
Добавьте эту новую функцию переопределения.
@Override
public String getBodyContentType() {
return "application/json";
}
У меня такая же проблема, и я получил решение в своем проекте:
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 используйте "StringRequest" вместо "JsonObjectRequest"
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;
}
И все работает в моем случае.
У меня эта ошибка, и теперь я исправлен. Я сделал то, что сказано в этой ссылке. Что вам нужно сделать, это
if (statusCode < 200 || statusCode > 299) {
throw new IOException();
}
с
if (statusCode < 200 || statusCode > 405) {
throw new IOException();
}
Надеюсь, что это поможет.
Я удалил this 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;
}
В Android 2.3 существует проблема с использованием Base64.encodeToString(), поскольку она вводит новую строку в HTTP-заголовке. См. Мой ответ на этот вопрос здесь, в SO.
Короткий ответ: Не используйте Base64.encodeToString(), но поместите уже закодированную строку.
Для этой ошибки может быть несколько причин. Один из кошек, как говорят другие, может быть, вы отсутствуете или неправильно задали заголовок Content-type. Если вы правильно реализованы, то другая возможная причина заключается в том, что вы отправляете параметры непосредственно с вашего URL-адреса. Может быть случай, когда params - это строка с некоторыми пробелами в ней. Эти пробелы вызывают проблемы в запросах GET через залп. Вам нужно найти другой способ. Вот и все.
Проверьте, используете ли вы правильный SDK
Для Android Studio/IntelliJIDEA:
File -> Project Structure -> Project -> Project SDK
Modules -> Check each modules "Module SDK"
Предпочтительно использовать API Google (x.x) вместо Android API