web-dev-qa-db-fra.com

Envoyer les paramètres codés par formulaire dans la demande de publication Android volley

Je veux faire un POST JSONObjectRequest avec les paramètres du formulaire urlencoded. Comment puis-je faire cela? J'ai essayé le code suivant, mais en vain.

final String api = "http://api.url";
final JSONObject jobj = new JSONObject();
jobj.put("Username", "usr");
jobj.put("Password", "passwd");
jobj.put("grant_type", "password");

final JsonObjectRequest jor = new JsonObjectRequest(

    Request.Method.POST, 
    api, jobj, 
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
            //do other things with the received JSONObject
        }
    }, 
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_LONG).show();
        }
    }) {

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

//add to the request queue
requestqueue.AddToRequestQueue(jor);

Je reçois une 400 mauvaise requête avec l'appel API! Comment puis-je le réparer?

35
user4071017

Après une longue et longue lutte, a trouvé la solution. Vous devez remplacer getBodyContentType() et retourner application/x-www-form-urlencoded; charset=UTF-8.

StringRequest jsonObjRequest = new StringRequest(

    Request.Method.POST,
    getResources().getString(R.string.base_url),
    new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            MyFunctions.toastShort(LoginActivity.this, response);
        }
    }, 
    new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d("volley", "Error: " + error.getMessage());
            error.printStackTrace();
            MyFunctions.croutonAlert(LoginActivity.this,
                MyFunctions.parseVolleyError(error));
            loading.setVisibility(View.GONE);
        }
    }) {

    @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("username", etUname.getText().toString().trim());
        params.put("password", etPass.getText().toString().trim());
        return params;
    }

};

AppController.getInstance().addToRequestQueue(jsonObjRequest);
73
Bala Vishnu
public static void DoPostStringResult(String url, Object Tag,
        final StringCallBack CallBack, Context context,
        final String body) {
    StringRequest request = new StringRequest(Request.Method.POST, url,
            new Listener<String>() {

                @Override
                public void onResponse(String result) {
                    CallBack.getResult(result);
                }

            }, new ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    CallBack.getError(error);
                }

            }) {
        // @Override
        // public Map<String, String> getHeaders() throws AuthFailureError {
        // //设置头信息
        // Map<String, String> map = new HashMap<String, String>();
        // map.put("Content-Type", "application/x-www-form-urldecoded");
        // return map;
        // }

        @Override
        public byte[] getBody() throws AuthFailureError {
            // TODO Auto-generated method stub
            return body.getBytes();
        }

        @Override
        public String getBodyContentType() {
            // TODO Auto-generated method stub
            return "application/x-www-form-urlencoded";
        }

        /**
         * 设置Volley网络请求的编码方式。。。。
         */
        @Override
        protected String getParamsEncoding() {
            return "utf-8";
        }

    };

    request.setRetryPolicy(new DefaultRetryPolicy(30 * 1000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

    request.setTag(Tag);
    VolleyUtils.getRequestQueue(context).add(request);
}

et votre corps doit être comme ceci "username=aa&password=bb&[email protected]"

9
TheOne_su

essayez d'utiliser StringRequest comme le code ci-dessous:

final String api = "http://api.url";
final StringRequest stringReq = new StringRequest(Request.Method.POST, api, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
  //do other things with the received JSONObject
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_LONG).show();
               }
            }) {
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> pars = new HashMap<String, String>();
                    pars.put("Content-Type", "application/x-www-form-urlencoded");
                    return pars;
                }

                @Override
                public Map<String, String> getParams() throws AuthFailureError {
                    Map<String, String> pars = new HashMap<String, String>();
                    pars.put("Username", "usr");
                    pars.put("Password", "passwd");
                    pars.put("grant_type", "password");
                    return pars;
                }
            };
  //add to the request queue
  requestqueue.AddToRequestQueue(stringReq);
5
mmlooloo

Volley ajoute un en-tête Content-Type juste avant l'envoi de la demande.

     /**
     * Returns the content type of the POST or PUT body.
     */
     public String getBodyContentType() {
         return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();
      }

Vous devez remplacer cela par un objet de demande personnalisé.

    public class CustomVolleyRequest extends StringRequest {
           ...

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

           ...
    }
2
shakrlabs.com

Je l'ai fait de la manière suivante (le type de contenu de mon corps de demande était application/x-www-form-urlencoded):

J'ai commenté aux endroits appropriés dans le code.

/**
     * @param url - endpoint url of the call
     * @param requestBody - I'm receiving it in json, without any encoding from respective activities.
     * @param listener - StringRequestListener is an Interface I created to handle the results in respective activities
     * @param activity - just for the context, skippable.
     * @param header - This contains my x-api-key
     */
    public void makePostRequest2(String url, final JSONObject requestBody, final StringRequestListener listener,
                                 Activity activity, final Map<String,String> header) {

        RequestQueue queue = VolleySingleton.getInstance().getRequestQueue();

        /**
         * You can skip this network testing.
         */
        if(!NetworkTester.isNetworkAvailable()) {
            Toast.makeText(MyApplication.getAppContext(),"Network error",Toast.LENGTH_SHORT).show();
            return;
        }


        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                listener.onResponse(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onError(error);
            }
        }) {
            /**
             * Setting the body-content type is the most important part.
             * @return
             * You don't have to write this method if your body content-type is application/x-www-form-urlencoded and encoding is charset=UTF-8
             * Because the base method is does the exact same thing.
             */
//            @Override
//            public String getBodyContentType() {
//                return "application/x-www-form-urlencoded; charset=UTF-8";
//            }


            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return header;
            }


            /**
             * I have copied the style of this method from its original method from com.Android.Volley.Request
             * @return
             * @throws AuthFailureError
             */
            @Override
            public byte[] getBody() throws AuthFailureError {

                Map<String, String> params = new HashMap<>();
                try {
                    params.put("grant_type","password");
                    params.put("username",requestBody.getString("username"));
                    params.put("password",requestBody.getString("password"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                //yeah, I copied this from the base method. 
                if (params != null && params.size() > 0) {
                    return encodeParameters(params, getParamsEncoding());
                }
                return null;


            }

        };

        queue.add(stringRequest);

    }

    /**
     * This method was private in the com.Android.Volley.Request class. I had to copy it here so as to encode my paramters.
     * @param params
     * @param paramsEncoding
     * @return
     */
    private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
        StringBuilder encodedParams = new StringBuilder();
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
                encodedParams.append('=');
                encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
                encodedParams.append('&');
            }
            return encodedParams.toString().getBytes(paramsEncoding);
        } catch (UnsupportedEncodingException uee) {
            throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
        }
    }
1
Akeshwar Jha
public void sendUserRegistrationRequest(final UserRequest userRequest, final ResponseListener responseListener) {
    String url = Api.POST_NRNA_REGISTRATION;

    StringRequest userRegistrationRequest = new StringRequest(Request.Method.POST, url, new com.Android.volley.Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            JSONObject jsonObject = GsonUtils.getJSONObject(response);
            LoggerUtils.log(TAG, "" + jsonObject.toString());

        }
    }, new com.Android.volley.Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            LoggerUtils.log(TAG, GsonUtils.toString(error));
            responseListener.onError(GsonUtils.toString(error));
        }
    }) {

        //use this if you have to use form posting : for application/x-www-form-urlencoded;
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            return GsonUtils.getHashMap(userRequest);
        }

        @Override
        public String getBodyContentType() {
            return "application/x-www-form-urlencoded; charset=UTF-8";
        }


    };
    VolleyRequestQueue.getInstance(context).addToRequestQueue(userRegistrationRequest);
}

Utilisez-le si vous devez envoyer comme "application/json"

        @Override
        public byte[] getBody() throws AuthFailureError {
            String jsonData = GsonUtils.toString(userRequest);
            return jsonData.getBytes();
        }

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




public class GsonUtils {

public static String TAG = GsonUtils.class.getSimpleName();

public static <T> T toObject(String data, Class<T> type) {
    Gson gson = new Gson();
    return gson.fromJson(data, type);
}

public static String toString(Object src) {
    if (src == null) {
        return null;
    }
    GsonBuilder builder = new GsonBuilder();
    builder.setPrettyPrinting();
    Gson gson = builder.create();
    return gson.toJson(src);
}


public static <T> T toObject(String data, Type type) {
    try {
        Gson gson = new Gson();
        return gson.fromJson(data, type);
    } catch (Exception ex) {
        Timber.v(ex.getMessage());
        return null;
    }
}


public static JSONObject getJSONObject(Object src) {
    String data = toString(src);
    LoggerUtils.log(TAG, data);
    try {
        return new JSONObject(data);
    } catch (JSONException e) {
        LoggerUtils.log(TAG, e.getMessage());
    }
    return null;
}


public static JSONObject getJSONObject(String data) {
    try {
        return new JSONObject(data);
    } catch (JSONException e) {
        LoggerUtils.log(TAG, e.getMessage());
    }
    return null;
}


public static HashMap<String, String> getHashMap(Object src) {
    String data = toString(src);
    LoggerUtils.log(TAG, data);
    return toObject(data, new TypeToken<HashMap<String, String>>() {
    }.getType());
}

}

0
Prabin Shrestha

Il n'y a pas de constructeur prédéfini dans JsonObjectRequest qui accepte les paramètres de publication, vous avez donc créé votre propre constructeur

Vous devez à la fois affecter votre Map à une variable déjà déclarée dans cette méthode dans votre constructeur, et vous devez également ajouter cette méthode

@Override
protected Map<String, String> getParams() throws AuthFailureError {
    return this.params;
}
0
CQM