Параметры сообщения 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()", но ни одно из этих переопределений не сработало для мне. Другим предложением было использование дополнительного вспомогательного класса, который в основном создает пользовательский запрос, но это исправление слишком сложно для моих нужд. Если это сводится к этому, я сделаю все, чтобы заставить его работать, но я надеюсь, что есть простая причина, почему мой код работает, а потом просто перестал, а также простое решение.

Ответы

Ответ 1

В итоге я использовал Volley StringRequest, потому что использовал слишком много времени, пытаясь заставить 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, но вместо этого использует строку.

Ответ 2

Вам просто нужно сделать 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.POST, 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);

Ответ 3

У меня была похожая проблема, но я обнаружил, что проблема была не на стороне клиента, а на стороне сервера. Когда вы отправляете JsonObject, вам нужно получить объект POST, подобный этому (на стороне сервера):

В PHP:

$json = json_decode(file_get_contents('php://input'), true);

Ответ 4

Вы можете использовать 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);

Ответ 5

Использование объекта 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 не является тем, что обычно требуется серверу?

Ответ 6

Использовать вспомогательный класс 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);

Ответ 7

Может помочь кому-то и сэкономить время. У меня была аналогичная проблема, код сервера искал заголовок Content-Type. Это делалось так:

if($request->headers->content_type == 'application/json' ){ //Parse JSON... }

Но Volley отправил заголовок следующим образом:

'application/json; charset?utf-8'

Изменение кода сервера на это привело к трюку:

if( strpos($request->headers->content_type, 'application/json') ){ //Parse JSON... 

Ответ 8

У меня была аналогичная проблема. Но я узнал, что проблема не на стороне сервера, но проблема в кеше. Вам необходимо очистить кэш RequestQueue.

RequestQueue requestQueue1 = Volley.newRequestQueue(context);
requestQueue1.getCache().clear();

Ответ 9

Вы можете сделать это следующим образом:

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 Почтовый запрос не работает

Ответ 10

Это действительно так. Я проанализировал ответ объекта 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);

Удачи! спокойной ночи!

Ответ 11

  ... Изначально это работало на меня.... Затем он внезапно перестал работать, и я не внес никаких изменений в код

если вы не внесли никаких изменений в ранее работающий код, тогда я предлагаю проверить другие параметры, такие как URL, так как IP-адрес может измениться, если вы используете свой собственный компьютер в качестве сервера!