web-dev-qa-db-fra.com

Passer le paramètre avec Volley POST

J'ai pu appeler un point de terminaison HTTP à l'aide de Postman et de ces paramètres:

{
    "name":"Val",
    "subject":"Test"
}

Cependant, je ne peux pas faire de même avec Volley via Android: voici essayer d'utiliser JSONRequest:

HashMap<String, String> params2 = new HashMap<String, String>();
        params.put("name", "Val");
        params.put("subject", "Test Subject");

        JsonObjectRequest jsObjRequest = new JsonObjectRequest
                (Request.Method.POST, Constants.CLOUD_URL, new JSONObject(params2), new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        mView.showMessage("Response: " + response.toString());
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO Auto-generated method stub
                        mView.showMessage(error.getMessage());

                    }
                });

        // Access the RequestQueue through your singleton class.
        VolleySingleton.getInstance(mContext).addToRequestQueue(jsObjRequest);

Et voici essayer StringRequest

private void postMessage(Context context, final String name, final String subject ){

        RequestQueue queue = Volley.newRequestQueue(context);
        StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                mView.showMessage(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }){
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<String, String>();
                params.put("name", name);
                params.put("subject", subject);

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String,String> params = new HashMap<String, String>();
                params.put("Content-Type","application/x-www-form-urlencoded");
                return params;
            }
        };
        queue.add(sr);
    }

Quand j'utilise JSONRequest, l'appel POSTs mais aucun paramètre n'est passé et quand j'utilise StringRequest j'obtiens l'erreur ci-dessous? Comment puis-je transmettre des données JSON à un appel Volley?

E/Volley: [13053] BasicNetwork.performRequest: Unexpected response code 400 for 

Voici le code du serveur qui gère la demande

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var helloRequest = await req.Content.ReadAsAsync<HelloRequest>();

    var name = helloRequest?.Name ?? "world";    
    var responseMessage = $"Hello {personToGreet}!";


    log.Info($"Message: {responseMessage}");


    return req.CreateResponse(HttpStatusCode.OK, $"All went well.");
}

public class HelloRequest
{
    public string Name { get; set; }
    public string Subject { get; set; }
}
8
Val Okafor

Le code du serveur attend qu'un objet JSON renvoie une chaîne ou plutôt une chaîne Json.

JsonObjectRequest

JSONRequest envoie un objet JSON dans le corps de la demande et attend un objet JSON dans la réponse. Puisque le serveur renvoie une chaîne, il finit par lancer ParseError

StringRequest

StringRequest envoie une demande avec le type de corps x-www-form-urlencoded mais puisque le serveur attend un objet JSON. Vous finissez par obtenir 400 mauvaises demandes

La solution

La solution consiste à changer le type de contenu dans la demande de chaîne en JSON et également à passer un objet JSON dans le corps. Puisqu'il attend déjà une chaîne que vous répondez, vous êtes bon là-bas. Le code pour cela devrait être le suivant.

StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        mView.showMessage(response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mView.showMessage(error.getMessage());
    }
}) {
    @Override
    public byte[] getBody() throws AuthFailureError {
        HashMap<String, String> params2 = new HashMap<String, String>();
        params2.put("name", "Val");
        params2.put("subject", "Test Subject");
        return new JSONObject(params2).toString().getBytes();
    }

    @Override
    public String getBodyContentType() {
        return "application/json";
    }
};

Il y a aussi un bogue ici dans le code du serveur

var responseMessage = $"Hello {personToGreet}!";

Devrait être

var responseMessage = $"Hello {name}!";
15
Naren

Ajoutez le type de contenu dans l'en-tête

@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;
}    
0
udayatom

Vous utilisez params.put au lieu de params2.put dans votre carte de hachage lors de la transmission des paramètres. parce que le nom de votre objet est params2

0
Muhmmad Umair