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; }
}
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}!";
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;
}
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