Los parámetros del poste de Volley JsonObjectRequest ya no funcionan


Estoy tratando de enviar parámetros POST en una Volley JsonObjectRequest. Inicialmente, estaba funcionando para mí, siguiendo lo que dice el código oficial de pasar un JSONObject que contiene los parámetros en el constructor de la JsonObjectRequest. Entonces, de repente dejó de funcionar y no he hecho ningún cambio en el código que estaba trabajando anteriormente. El servidor ya no reconoce que se están enviando parámetros POST. Aquí está mi código:

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);

Aquí está el código PHP simple tester en el servidor:

$response = array("tag" => $_POST["tag"]);
echo json_encode($response);

La respuesta que recibo es {"tag":null}
Ayer, funcionó bien y respondía con {"tag":"test"}
No he cambiado nada, pero hoy ya no funciona.

En el constructor de código fuente de Volley javadoc dice que puede pasar un JSONObject en el constructor para enviar parámetros post en " @param JSONRequest": https://android.googlesource.com/platform/frameworks/volley/+/master/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java

/**
 * Crea una nueva solicitud.
 * método @param el método HTTP a usar
 * @param url URL para obtener el JSON desde
 * @param JSONRequest A {@link JSONObject} para publicar con la solicitud. Null está permitido y
 * indica que no se publicarán parámetros junto con solicitud.

He leído otros posts con preguntas similares, pero las soluciones no han funcionado para mí:

Volley JsonObjectRequest Post request not working

Volley Post JsonObjectRequest ignorando parámetros mientras se usa getHeader y getParams

Volley no envía una solicitud post con parámetros.

He intentado establecer el JSONObject en el constructor JsonObjectRequest a null, luego sobreescribiendo y estableciendo el parámetros en los métodos" getParams ()"," getBody () "y" getPostParams ()", pero ninguna de esas anulaciones ha funcionado para mí. Otra sugerencia fue usar una clase auxiliar adicional que básicamente crea una solicitud personalizada, pero esa solución es un poco demasiado compleja para mis necesidades. Si se reduce a ello, haré cualquier cosa para que funcione, pero espero que haya una razón simple de por qué mi código era trabajando, y luego sólo detenido, y también un simple solución.

Author: Community, 2015-04-04

11 answers

Solo tienes que hacer un JSONObject a partir de tu HashMap de parámetros:

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);
 32
Author: Philippe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-11 22:09:04

Terminé usando StringRequest de Volley en su lugar, porque estaba usando demasiado tiempo valioso tratando de hacer que JsonObjectRequest funcione.

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);

Esto funcionó para mí. Es tan simple como JsonObjectRequest, pero usa una cadena en su lugar.

 31
Author: Joshua C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-24 14:48:33

Tuve un problema similar, pero descubrí que el problema no estaba en el lado del cliente, sino en el lado del servidor. Cuando envías un JsonObject, necesitas obtener el objeto POST así (en el lado del servidor):

En PHP:

$json = json_decode(file_get_contents('php://input'), true);
 8
Author: Gonzalo Ortellado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-07 10:12:15

Puede usar StringRequest para hacer las mismas cosas que puede hacer con JsonObjectRequest, al mismo tiempo que puede enviar fácilmente parámetros POST. Lo único que tienes que hacer es crear un JSONObject a partir de la cadena de solicitud que obtienes, y desde allí puedes continuar como si fuera 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);
 7
Author: itamar8910,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-07 22:24:55

Usar el objeto JSONObject para enviar parámetros significa que los parámetros estarán en formato JSON en el cuerpo de la solicitud HTTP POST:

Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");
params.put("tag2", "test2");
JSONObject jsonObj = new JSONObject(params);

Creará este objeto JSON y lo insertará en el cuerpo de la solicitud HTTP POST:

{"tag":"test","tag2":"test2"}

Entonces el servidor debe decodificar el JSON para entender estos parámetros POST.

Pero normalmente los parámetros HTTP POST se escriben en el cuerpo como:

tag=test&tag2=test2

Pero ahora aquí la pregunta es ¿por qué Volea se establece de esta manera?

Un servidor lectura de un método HTTP POST debería por estándar siempre tratar de leer parámetros también en JSON (que no sea en texto plano) y por lo tanto un servidor que no cumple es un servidor malo?

O en su lugar un cuerpo HTTP POST con parámetros en JSON no es lo que normalmente un servidor quiere?

 2
Author: Adriano G. V. Esposito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-09 09:04:15

Use la clase auxiliar CustomJsonObjectRequest mencionada aquí.

E implementar así -

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);
 1
Author: Faiz Siddiqui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:33

Podría ayudar a alguien y ahorrarte algo de tiempo pensando. Tuve un problema similar, el código del servidor estaba buscando el encabezado Content-Type. Lo estaba haciendo de esta manera:

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

Pero Volley estaba enviando el encabezado de esta manera:

'application/json; charset?utf-8'

Cambiar el código del servidor a esto hizo el truco:

if( strpos($request->headers->content_type, 'application/json') ){ //Parse JSON... 
 1
Author: kuffel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-21 20:48:31

Tuve un problema similar. Pero descubrí que el problema no estaba en el lado del servidor, pero el problema es sobre la caché. Tienes que limpiar tu Caché de RequestQueue.

RequestQueue requestQueue1 = Volley.newRequestQueue(context);
requestQueue1.getCache().clear();
 1
Author: Swapnil Naukudkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-07 12:32:21

Puedes hacerlo de esta manera:

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);

Según CustomRequest enlace a continuación Volley JsonObjectRequest Post request no funciona

 1
Author: Vishal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-16 04:41:54

Funciona.
Analicé la respuesta del objeto json usando esto:- funciona como un encanto.

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);

¡Buena suerte! ¡Buenas noches!

 0
Author: Debasish Ghosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-11 19:46:54

"...Al principio, estaba funcionando para mí. ....Entonces de repente dejó de funcionar y No he hecho ningún cambio al código "

Si no ha realizado ningún cambio en un código que funciona anteriormente, le sugiero que verifique otros parámetros, como URL , ya que la dirección IP puede cambiar si está utilizando su propia computadora como servidor.

 -1
Author: Charden Daxicen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-19 09:43:03