Отправьте параметры формы с urlencoded в почтовый запрос андроид-залп

Я хочу сделать POST JSONObjectRequest с параметрами urlencoded. Как я могу это сделать? Я пробовал следующий код, но безрезультатно.

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

Я получаю 400 плохих запросов с вызовом api! Как я могу это исправить?

Дала долгую борьбу, нашла решение. Вам нужно переопределить getBodyContentType () и вернуть «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); 
 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); } 

И ваше тело должно быть таким, как «username = aa&password=bb&email=XXX@XXX.com».

Попробуйте использовать StringRequest как StringRequest ниже:

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

Волейбол добавляет заголовок Content-Type прямо перед отправкой запроса.

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

Вы должны переопределить это с помощью настраиваемого объекта запроса.

  public class CustomVolleyRequest extends StringRequest { ... @Override public String getBodyContentType() { return "application/json"; } ... } 

Я сделал это следующим образом (контент-тип моего тела запроса был application / x-www-form-urlencoded):

Я прокомментировал в соответствующих местах кода.

 /** * @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); } } 

В JsonObjectRequest нет конструктора предварительного построения, который принимает параметры сообщения, поэтому вы создали свой собственный конструктор

Вы должны назначить свою Карту уже объявленной переменной в этом методе внутри вашего конструктора, и вы также должны добавить этот метод

 @Override protected Map<String, String> getParams() throws AuthFailureError { return this.params; } 
 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); } 

Используйте это, если вам нужно отправить как "application / json"

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