Android Volley - BasicNetwork.performRequest: Неожиданный код ответа 400
Проблема:
Я пытаюсь получить доступ к REST API, который будет возвращать объект JSON для различных кодов статуса HTTP (400, 403, 200 и т.д.) с помощью Volley.
Для любого HTTP-статуса, отличного от 200, кажется, что "неожиданный код ответа 400" является проблемой. Кто-нибудь есть способ обойти эту "ошибку"?
Код:
protected void getLogin() {
final String mURL = "https://somesite.com/api/login";
EditText username = (EditText) findViewById(R.id.username);
EditText password = (EditText) findViewById(R.id.password);
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", username.getText().toString());
params.put("password", password.getText().toString());
JsonObjectRequest req = new JsonObjectRequest(mURL, new JSONObject(
params), new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONObject obj = response
.getJSONObject("some_json_obj");
Log.w("myApp",
"status code..." + obj.getString("name"));
// VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.w("error in response", "Error: " + error.getMessage());
}
});
// add the request object to the queue to be executed
AppController.getInstance().addToRequestQueue(req);
}
Ответы
Ответ 1
Один из способов сделать это без изменения исходного кода Volley
- проверить данные ответа в VolleyError
и проанализировать его самостоятельно.
Начиная с f605da3 commit
, Volley
генерирует исключение ServerError
, которое содержит необработанное сетевой ответ.
Итак, вы можете сделать что-то подобное в своем прослушивателе ошибок:
/* import com.android.volley.toolbox.HttpHeaderParser; */
public void onErrorResponse(VolleyError error) {
// As of f605da3 the following should work
NetworkResponse response = error.networkResponse;
if (error instanceof ServerError && response != null) {
try {
String res = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
// Now you can use any deserializer to make sense of data
JSONObject obj = new JSONObject(res);
} catch (UnsupportedEncodingException e1) {
// Couldn't properly decode data to string
e1.printStackTrace();
} catch (JSONException e2) {
// returned data is not JSONObject?
e2.printStackTrace();
}
}
}
В будущем, если Volley
изменится, вы можете выполнить описанный выше подход, когда вам нужно проверить VolleyError
на необработанные данные, которые были отправлены сервером и проанализировать его.
Я надеюсь, что они реализуют это TODO
, упомянутое в исходном файле .
Ответ 2
@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;
}
Вам нужно добавить Content-Type в заголовок.
Ответ 3
У меня тоже была такая же ошибка, но в моем случае я вызывал url с пробелами.
Затем я исправил его, выполнив парсинг, как показано ниже.
String url = "Your URL Link";
url = url.replaceAll(" ", "%20");
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
...
...
...
Ответ 4
Попробуйте это...
StringRequest sr = new StringRequest(type,url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// valid response
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// error
}
}){
@Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("username", username);
params.put("password", password);
params.put("grant_type", "password");
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
// Removed this line if you dont need it or Use application/json
// params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
Ответ 5
Вы хотите получить коды статуса?
VolleyError
имеет тип переменной-члена NetworkResponse
и является общедоступным.
Вы можете получить доступ к error.networkResponse.statusCode
для кода ошибки http.
Я надеюсь, что это будет полезно для вас.
Ответ 6
в моем случае, я не писал reg_url с: 8080.
String reg_url = " http://192.168.29.163:8080/register.php";
Ответ 7
Просто обновить все, после некоторых обсуждений, я решил использовать Async Http Client вместо этого, чтобы решить мою более раннюю проблему. Библиотека позволяет использовать более чистый подход для обработки HTTP-ответов, особенно в тех случаях, когда объекты JSON возвращаются во всех сценариях/статусах HTTP.
protected void getLogin() {
EditText username = (EditText) findViewById(R.id.username);
EditText password = (EditText) findViewById(R.id.password);
RequestParams params = new RequestParams();
params.put("username", username.getText().toString());
params.put("password", password.getText().toString());
RestClient.post(getHost() + "api/v1/auth/login", params,
new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
JSONObject response) {
try {
//process JSONObject obj
Log.w("myapp","success status code..." + statusCode);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers,
Throwable throwable, JSONObject errorResponse) {
Log.w("myapp", "failure status code..." + statusCode);
try {
//process JSONObject obj
Log.w("myapp", "error ..." + errorResponse.getString("message").toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
Ответ 8
То, что я сделал, добавило дополнительный "/" к моему URL, например:
String url = "http://www.google.com"
в
String url = "http://www.google.com/"
Ответ 9
менять
public static final String URL = " http://api-Location ";
в
public static final String URL = " https://api-Location "
это происходит потому, что я использую приложение 000webhostapp