Volley JsonObjectRequest Параметры сообщения больше не работают
Я пытаюсь отправить параметры POST в запросе JsonObjectRequest. Первоначально это работало для меня, следуя указаниям официального кода, передавая JSONObject, содержащий параметры, в конструкторе JsonObjectRequest. Затем он внезапно перестал работать, и я не внес никаких изменений в код, который ранее работал. Сервер больше не распознает, что отправляются какие-либо параметры POST. Вот мой код:
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";
// POST parameters
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");
JSONObject jsonObj = new JSONObject(params);
// Request a json response from the provided URL
JsonObjectRequest jsonObjRequest = new JsonObjectRequest
(Request.Method.POST, url, jsonObj, new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response)
{
Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
});
// Add the request to the RequestQueue.
queue.add(jsonObjRequest);
Вот простой код PHP тестера на сервере:
$response = array("tag" => $_POST["tag"]);
echo json_encode($response);
Ответ я получаю {"tag":null}
Вчера все работало нормально и отвечало {"tag":"test"}
Я ничего не изменил, но сегодня он больше не работает.
В конструкторе исходного кода Volley javadoc говорится, что вы можете передать JSONObject в конструкторе для отправки параметров публикации по адресу "@param jsonRequest": https://android.googlesource.com/platform/frameworks/volley/+/master/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java
/ **
* Создает новый запрос.
* @param method метод HTTP для использования
* @param url URL для получения JSON из
* @param jsonRequest A {@link JSONObject} для публикации с запросом. Нуль разрешен и
* указывает на то, что параметры не будут опубликованы вместе с запросом.
Я читал другие посты с похожими вопросами, но решения не сработали для меня:
Volley JsonObjectRequest Отправить запрос не работает
Volley Post JsonObjectRequest игнорирует параметры при использовании getHeader и getParams
Залп не отправлял почтовый запрос с параметрами.
Я попытался установить для JSONObject в конструкторе JsonObjectRequest значение null, затем переопределить и установить параметры в методах "getParams()", "getBody()" и "getPostParams()", но ни одно из этих переопределений не сработало для мне. Другим предложением было использование дополнительного вспомогательного класса, который в основном создает пользовательский запрос, но это исправление слишком сложно для моих нужд. Если дело доходит до этого, я сделаю все, чтобы это заработало, но я надеюсь, что есть простая причина того, почему мой код работал, а затем просто остановился, а также простое решение.
15 ответов
Вместо этого я использовал StringRequest от Volley, потому что тратил слишком много драгоценного времени, пытаясь заставить JsonObjectRequest работать.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";
StringRequest strRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
@Override
public void onResponse(String response)
{
Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
})
{
@Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");
return params;
}
};
queue.add(strRequest);
Это сработало для меня. Это так же просто, как JsonObjectRequest, но вместо этого используется строка.
Вам просто нужно сделать JSONObject из вашего HashMap параметров:
String url = "https://www.youraddress.com/";
Map<String, String> params = new HashMap();
params.put("first_param", 1);
params.put("second_param", 2);
JSONObject parameters = new JSONObject(params);
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.GET, url, parameters, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
//TODO: handle success
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
//TODO: handle failure
}
});
Volley.newRequestQueue(this).add(jsonRequest);
У меня была похожая проблема, но я обнаружил, что проблема была не на стороне клиента, а на стороне сервера. Когда вы отправляете JsonObject
вам нужно получить объект POST следующим образом (на стороне сервера):
В PHP:
$json = json_decode(file_get_contents('php://input'), true);
Вы можете использовать StringRequest, чтобы делать то же самое, что и JsonObjectRequest, при этом все еще имея возможность легко отправлять параметры POST. Единственное, что вам нужно сделать, это создать JsonObject из строки запроса, которую вы получаете, и оттуда вы можете продолжить, как если бы это был JsonObjectRequest.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
//Creating JsonObject from response String
JSONObject jsonObject= new JSONObject(response.toString());
//extracting json array from response string
JSONArray jsonArray = jsonObject.getJSONArray("arrname");
JSONObject jsonRow = jsonArray.getJSONObject(0);
//get value from jsonRow
String resultStr = jsonRow.getString("result");
} catch (JSONException e) {
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("parameter",param);
return parameters;
}
};
requestQueue.add(stringRequest);
Используйте упомянутый здесь вспомогательный класс CustomJsonObjectRequest.
и реализовать как это -
CustomJsonObjectRequest request = new CustomJsonObjectRequest(Method.POST, URL, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(getActivity(), response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "Error.", Toast.LENGTH_SHORT).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
params.put("password", password);
return params;
}
};
VolleySingleton.getInstance().addToRequestQueue(request);
Использование объекта JSONObject для отправки параметров означает, что параметры будут в формате JSON в теле запроса HTTP POST:
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");
params.put("tag2", "test2");
JSONObject jsonObj = new JSONObject(params);
Создаст этот объект JSON и вставит его в тело HTTP-запроса POST:
{"tag":"test","tag2":"test2"}
Затем сервер должен декодировать JSON, чтобы понять эти параметры POST.
Но обычно параметры HTTP POST записываются в теле как:
tag=test&tag2=test2
Но СЕЙЧАС здесь возникает вопрос, почему волейбол настроен таким образом?
Сервер, читающий метод HTTP POST, должен по стандарту всегда пытаться читать параметры также в формате JSON (кроме обычного текста), и поэтому сервер, который не выполняет, является плохим сервером?
Или вместо этого тело HTTP POST с параметрами в JSON - это не то, чего обычно хочет сервер?
Вы можете сделать это следующим образом:
CustomRequest request = new CustomRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// Toast.makeText(SignActivity.this, response.toString(), Toast.LENGTH_SHORT).show();
Log.d("response",""+response.toString());
String status = response.optString("StatusMessage");
String actionstatus = response.optString("ActionStatus");
Toast.makeText(SignActivity.this, ""+status, Toast.LENGTH_SHORT).show();
if(actionstatus.equals("Success"))
{
Intent i = new Intent(SignActivity.this, LoginActivity.class);
startActivity(i);
finish();
}
dismissProgress();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(SignActivity.this, "Error."+error.toString(), Toast.LENGTH_SHORT).show();
Log.d("response",""+error.toString());
dismissProgress();
}
}) {
@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Email", emailval);
params.put("PassWord", passwordval);
params.put("FirstName", firstnameval);
params.put("LastName", lastnameval);
params.put("Phone", phoneval);
return params;
}
};
AppSingleton.getInstance(SignActivity.this.getApplicationContext()).addToRequestQueue(request, REQUEST_TAG);
согласно CustomRequest ниже ссылка Volley JsonObjectRequest Отправить запрос не работает
Это работает.
Я проанализировал ответ объекта json, используя это:- работает как шарм.
String tag_string_req = "string_req";
Map<String, String> params = new HashMap<String, String>();
params.put("user_id","CMD0005");
JSONObject jsonObj = new JSONObject(params);
String url="" //your link
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, jsonObj, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("responce", response.toString());
try {
// Parsing json object response
// response will be a json object
String userbalance = response.getString("userbalance");
Log.d("userbalance",userbalance);
String walletbalance = response.getString("walletbalance");
Log.d("walletbalance",walletbalance);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppControllerVolley.getInstance().addToRequestQueue(jsonObjReq, tag_string_req);
удачи! доброй ночи!
Может помочь кому-то и сэкономить время на размышления. У меня была похожая проблема, код сервера искал заголовок Content-Type. Это делалось так:
if($request->headers->content_type == 'application/json' ){ //Parse JSON... }
Но Волли отправлял заголовок так:
'application/json; charset?utf-8'
Изменение кода сервера для этого сделало свое дело:
if( strpos($request->headers->content_type, 'application/json') ){ //Parse JSON...
У меня была похожая проблема. Но я обнаружил, что проблема не в серверной части, а в кеше. Вы должны очистить кэш RequestQueue.
RequestQueue requestQueue1 = Volley.newRequestQueue(context);
requestQueue1.getCache().clear();
VolleySingleton.getInstance()
.add(new StringRequest(Request.Method.POST, urlToTest, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// do stuff...
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// exception
}
}) {
@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
@Override
protected Map<String, String> getParams() {
return ServerApi.getRequiredParamsRequest(context);
}
}
);
Это сработало для меня, можно попробовать это для вызова с запросом и ответом типа Volley для Json.
public void callLogin(String sMethodToCall, String sUserId, String sPass) {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.POST, ConstantValues.ROOT_URL_LOCAL + sMethodToCall.toString().trim(), addJsonParams(sUserId, sPass),
// JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("onResponse", response.toString());
Toast.makeText(VolleyMethods.this, response.toString(), Toast.LENGTH_LONG).show(); // Test
parseResponse(response);
// msgResponse.setText(response.toString());
// hideProgressDialog();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("onErrorResponse", "Error: " + error.getMessage());
Toast.makeText(VolleyMethods.this, error.toString(), Toast.LENGTH_LONG).show();
// hideProgressDialog();
}
}) {
/**
* Passing some request headers
*/
@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;
}
};
requestQueue.add(jsonObjectRequest);
}
public JSONObject addJsonParams(String sUserId, String sPass) {
JSONObject jsonobject = new JSONObject();
try {
// {"id":,"login":"secretary","password":"password"}
///***//
Log.d("addJsonParams", "addJsonParams");
// JSONObject jsonobject = new JSONObject();
// JSONObject jsonobject_one = new JSONObject();
//
// jsonobject_one.put("type", "event_and_offer");
// jsonobject_one.put("devicetype", "I");
//
// JSONObject jsonobject_TWO = new JSONObject();
// jsonobject_TWO.put("value", "event");
// JSONObject jsonobject = new JSONObject();
//
// jsonobject.put("requestinfo", jsonobject_TWO);
// jsonobject.put("request", jsonobject_one);
jsonobject.put("id", "");
jsonobject.put("login", sUserId); // sUserId
jsonobject.put("password", sPass); // sPass
// js.put("data", jsonobject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return jsonobject;
}
public void parseResponse(JSONObject response) {
Boolean bIsSuccess = false; // Write according to your logic this is demo.
try {
JSONObject jObject = new JSONObject(String.valueOf(response));
bIsSuccess = jObject.getBoolean("success");
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(VolleyMethods.this, "" + e.toString(), Toast.LENGTH_LONG).show(); // Test
}
}
Надеюсь, я еще не опоздал на вечеринку: проблема на стороне сервера. Если вы используете PHP, добавьте следующие строки в верхней части файла php api (после включения)
$inputJSON = file_get_contents('php://input');
if(get_magic_quotes_gpc())
{
$param = stripslashes($inputJSON);
}
else
{
$param = $inputJSON;
}
$input = json_decode($param, TRUE);
Затем, чтобы получить ваши значения
$tag= $input['tag'];
Используйте GET вместо POST для использования JsonObjectRequest
"... Первоначально это работало на меня... Потом вдруг оно перестало работать, и я не внес никаких изменений в код"
если вы не внесли никаких изменений в ранее работающий код, тогда я предлагаю проверить другие параметры, такие как URL, так как IP-адрес может измениться, если вы используете свой собственный компьютер в качестве сервера!