web-dev-qa-db-fra.com

Paramètres Volley JsonObjectRequest Post ne fonctionnent plus

J'essaie d'envoyer les paramètres POST dans un Volley JsonObjectRequest. Initialement, ça fonctionnait pour moi en suivant ce que le code officiel dit de faire passer un JSONObject contenant les paramètres dans le constructeur de JsonObjectRequest. Puis tout à coup, il a cessé de fonctionner et je n’ai apporté aucune modification au code qui fonctionnait auparavant. Le serveur ne reconnaît plus que les paramètres POST sont envoyés. Voici mon code:

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

Voici le code du testeur simple PHP sur le serveur:

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

La réponse que je reçois est {"tag":null}
Hier, cela a bien fonctionné et répondait avec {"tag":"test"}
Je n'ai pas changé une seule chose, mais aujourd'hui cela ne fonctionne plus.

Dans le constructeur de code source Volley, javadoc, il est indiqué que vous pouvez passer un objet JSON dans le constructeur pour envoyer les paramètres de publication à "@param jsonRequest": https://Android.googlesource.com/platform/frameworks/volley/ +/master/src/principal/Java/com/Android/volley/toolbox/JsonObjectRequest.Java

/ **
* Crée une nouvelle demande.
* méthode @param la méthode HTTP à utiliser
* @param url URL pour récupérer le JSON
* @param jsonRequest Un {@link JSONObject} à publier avec la demande. Null est autorisé et
* Indique qu'aucun paramètre ne sera publié avec la demande.

J'ai lu d'autres articles avec des questions similaires, mais les solutions n'ont pas fonctionné pour moi:

La requête de publication de Volley JsonObjectRequest ne fonctionne pas

Volley Post JsonObjectRequest ignorant les paramètres lors de l'utilisation de getHeader et getParams

Volley n'envoie pas une demande de poste avec des paramètres.

J'ai essayé de définir le paramètre JSONObject du constructeur JsonObjectRequest sur null, puis de redéfinir les paramètres dans les méthodes "getParams ()", "getBody ()" et "getPostParams ()", mais aucun de ces substitutions n'a fonctionné moi. Une autre suggestion consistait à utiliser une classe d'assistance supplémentaire qui crée une demande personnalisée, mais cette solution est un peu trop complexe pour mes besoins. Si tout se résume à cela, je ferai n'importe quoi pour que cela fonctionne, mais j'espère qu'il y a une raison simple pour laquelle mon code était fonctionne, puis juste arrêté, et aussi une solution simple.

26
Joshua C.

J'ai fini par utiliser StringRequest de Volley, parce que j'utilisais trop de temps précieux pour essayer de faire fonctionner 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);

Cela a fonctionné pour moi. C'est aussi simple que JsonObjectRequest, mais utilise plutôt une chaîne.

32
Joshua C.

Vous devez juste créer un JSONObject à partir de votre HashMap de paramètres:

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

J'ai eu un problème similaire, mais j'ai découvert que le problème n'était pas du côté client, mais du côté serveur. Lorsque vous envoyez une JsonObject, vous devez obtenir l'objet POST comme ceci (côté serveur):

En PHP:

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

Vous pouvez utiliser StringRequest pour faire la même chose que vous pouvez avec JsonObjectRequest, tout en pouvant envoyer facilement des paramètres POST. La seule chose à faire est de créer un JsonObject à partir de la chaîne de requête que vous obtenez et de continuer à partir de là, comme si c'était 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
itamar8910

L'utilisation de l'objet JSONObject pour envoyer des paramètres signifie que les paramètres seront au format JSON dans le corps de la requête HTTP POST:

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

Crée cet objet JSON et l'insère dans le corps de la demande HTTP POST:

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

Ensuite, le serveur doit décoder le JSON pour comprendre ces paramètres POST.

Mais normalement, les paramètres HTTP POST sont écrits dans le corps comme:

tag=test&tag2=test2

Mais MAINTENANT, la question est de savoir pourquoi Volley est défini de cette manière?

Un serveur qui lit une méthode HTTP POST doit normalement toujours essayer de lire les paramètres également en JSON (autrement qu'en texte brut). Par conséquent, un serveur qui n'accomplit pas est un mauvais serveur?

Ou plutôt un corps HTTP POST avec des paramètres en JSON n'est pas ce que veut normalement un serveur?

J'ai eu le même problème. Mais j'ai découvert que le problème n'était pas du côté serveur, mais le problème concernait le cache. Vous devez vider votre cache RequestQueue. 

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

Cela pourrait aider quelqu'un et vous faire gagner du temps en pensant ... J'ai un problème similaire, le code du serveur recherchait l'en-tête Content-Type. C'était comme ça:

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

Mais Volley envoyait l'en-tête comme ceci:

'application/json; charset?utf-8'

Changer le code du serveur à ceci a fait le tour:

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

Utilisez la classe d’assistance CustomJsonObjectRequest mentionnée ici .

et mettre en œuvre comme ça -

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
Faiz Siddiqui

Vous pouvez le faire de cette façon:

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

selon le lien CustomRequest ci-dessous La requête de publication de Volley JsonObjectRequest ne fonctionne pas

1
Vishal

Ça marche.
J'ai analysé la réponse d'objet Json en utilisant ceci:.

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

bonne chance! .__ bonne nuit!

0
Debasish Ghosh