Senden Sie formular-urlencodierte Parameter in der Post-Request-Android-Volley

Lesezeit: 1 Minute

Benutzeravatar von user4071017
Benutzer4071017

Ich möchte eine POST JSONObjectRequest mit Formular-urlencodierten Parametern erstellen. Wie kann ich das machen? Ich habe den folgenden Code versucht, aber ohne Erfolg.

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

Ich erhalte eine 400 Bad Request mit dem API-Aufruf! Wie kann ich es reparieren?

Benutzeravatar von Bala Vishnu
Bala Vishnu

Nach langem Ringen die Lösung gefunden. Sie müssen überschreiben getBodyContentType() und zurück 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);

  • der perfekte Weg <3

    – Amir Sasani

    10. Januar 2017 um 11:14 Uhr

  • aber in meinem Fall funktioniert es nicht. Ich verwende die DELETE-Methode eher POST

    – Abdul Waheed

    13. Juni 2017 um 6:48 Uhr

  • @Roel Gerade nachgesehen, ja, ist es.

    – daka

    19. Januar 2019 um 13:36 Uhr

  • Hey Bala, könntest du dir bitte meinen vorgeschlagenen Vorschlag ansehen

    – daka

    19. Januar 2019 um 20:48 Uhr

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

und Ihr Körper muss wie folgt lauten: “username=aa&password=bb&[email protected]

  • Hallo, können Sie mir sagen, wie es funktioniert. Denn hier stehe ich vor einem Bettanforderungsfehler für den obigen Code.

    – Jatinkumar Patel

    26. Mai 2017 um 7:05 Uhr

versuchen Sie es mit StringRequest wie unten code:

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

  • Dies bedeutet, dass die von Ihnen gestellte Anfrage falsch ist. Überprüfen Sie die API-Dokumente und was Sie senden, und stellen Sie sicher, dass es korrekt ist. können Sie Ihre Anfrage mit anderen Sachen senden, z Postman oder RESTClient und sag mir das Ergebnis?

    – mmlooo

    23. September 2014 um 16:40 Uhr


  • stellst du alles wie mein code ein, setze header application/x-www-form-urlencoded und params?

    – mmlooo

    23. September 2014 um 16:47 Uhr

  • Die Antwort sollte meiner Meinung nach vom Typ String sein, ansonsten ist alles so, wie Sie es mir gesagt haben !!

    – Benutzer4071017

    23. September 2014 um 17:03 Uhr

  • ich verstehe nicht everything is as you told me !

    – mmlooo

    23. September 2014 um 17:05 Uhr

  • Ich habe alles genau so geschrieben, wie Sie oben gezeigt haben, außer für den Antworttyp String

    – Benutzer4071017

    23. September 2014 um 17:12 Uhr

Ich habe es folgendermaßen gemacht (der Inhaltstyp meines Anfragetexts war application/x-www-form-urlencoded):

Ich habe an entsprechenden Stellen im Code kommentiert.

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

Volley fügt direkt vor dem Versenden der Anfrage einen Content-Type-Header hinzu.

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

Sie müssen dies mit einem benutzerdefinierten Anforderungsobjekt überschreiben.

    public class CustomVolleyRequest extends StringRequest {
           ...

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

           ...
    }

Benutzeravatar von bayramcicek
bayramcicek

Ich suchte nach Antworten in der Kotlin-Sprache. Senden Sie x-www-form-urlencoded-Parameter in der Post-Anfrage mit Android-Volley in Kotlin-Sprache:

    val queue = Volley.newRequestQueue(this)

    val stringRequest: StringRequest = object : StringRequest(
        Method.POST,
        link,
        Response.Listener { response ->
            Log.i("response:", response)
        },

        Response.ErrorListener { error ->
            Log.i("response error:", "$error")
            error.printStackTrace()
        }) {
        override fun getBodyContentType(): String {
            return "application/x-www-form-urlencoded"
        }

        override fun getHeaders(): Map<String, String> {
            val headers: MutableMap<String, String> =
                HashMap()
            headers["Content-Type"] = "application/x-www-form-urlencoded"
            headers["Accept"] = "application/json"
            return headers
        }

        @Throws(AuthFailureError::class)
        override fun getParams(): Map<String, String> {
            val params: MutableMap<String, String> =
                HashMap()
            params["value1"] = "value1"
            params["value2"] = "value2"
            return params
        }
    }

    queue.add(stringRequest)

Es gibt keinen vorgefertigten Konstruktor in JsonObjectRequest das Post-Parameter akzeptiert, also haben Sie Ihren eigenen Konstruktor erstellt

Sie müssen Ihre Map sowohl einer bereits deklarierten Variablen in dieser Methode innerhalb Ihres Konstruktors zuweisen als auch diese Methode hinzufügen

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

  • Sie müssen Ihre Map sowohl einer bereits deklarierten Variablen in dieser Methode innerhalb Ihres Konstruktors zuweisen Bitte erkläre!!

    – Benutzer4071017

    23. September 2014 um 16:38 Uhr


  • @ user4071017 ok, du musst die Datei ändern JsonObjectRequest.java in Ihrem Volley-Projekt. Fügen Sie den Code hinzu Map<String, String> param; dann müssen Sie in Ihrem Konstruktor hinzufügen this.params = jobj;

    – CQM

    23. September 2014 um 16:49 Uhr


  • @user4071017 Entschuldigung, Sie müssen die Java-Grundlagen lernen, um fortzufahren.

    – CQM

    23. September 2014 um 18:19 Uhr

  • Alles klar, lass es mich versuchen. In meiner Volley-Bibliothek gibt es also eine Datei namens JsonObjectRequest.java, in der ich eine neue Variable namens Map hinzufüge Parameter, und ihm dann im Konstruktor meinen jobj zuweisen? Wie kann ich einer Karte ein Jsonobject zuweisen?

    – Benutzer4071017

    23. September 2014 um 19:14 Uhr

1431740cookie-checkSenden Sie formular-urlencodierte Parameter in der Post-Request-Android-Volley

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy