46 Stimmen

Senden Sie formulierte Parameter in einem POST-Anforderung Android Volley

Ich möchte einen POST JSONObjectRequest mit urlcodierten Formparametern 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() {
        @Override
        public void onResponse(JSONObject response) {
            Toast.makeText(getApplicationContext(), "Login erfolgreich!", Toast.LENGTH_LONG).show();
            //andere Dinge mit dem empfangenen JSONObject machen
        }
    }, 
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getApplicationContext(), "Fehler!", Toast.LENGTH_LONG).show();
        }
    }) {

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

//der Anforderungswarteschlange hinzufügen
requestqueue.AddToRequestQueue(jor);

Ich erhalte einen 400 Bad Request mit dem API-Aufruf! Wie kann ich das beheben?

90voto

Bala Vishnu Punkte 2540

Nach langem Kampf habe ich die Lösung gefunden. Sie müssen getBodyContentType() überschreiben und application/x-www-form-urlencoded; charset=UTF-8 zurückgeben.

StringRequest jsonObjRequest = new StringRequest(

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

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

        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d("volley", "Fehler: " + 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 getParams() throws AuthFailureError {
        Map params = new HashMap();
        params.put("username", etUname.getText().toString().trim());
        params.put("password", etPass.getText().toString().trim());
        return params;
    }

};

AppController.getInstance().addToRequestQueue(jsonObjRequest);

9voto

TheOne_su Punkte 669
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() {

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

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

            }) {
        // @Override
        // public Map getHeaders() throws AuthFailureError {
        // //
        // Map map = new HashMap();
        // 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 dein Körper muss so aussehen "username=aa&password=bb&email=XXX@XXX.com"

5voto

mmlooloo Punkte 18937

Versuchen Sie, StringRequest wie im folgenden Code zu verwenden:

final String api = "http://api.url";
final StringRequest stringReq = new StringRequest(Request.Method.POST, api, new Response.Listener() {
                @Override
                public void onResponse(JSONObject response) {
                    Toast.makeText(getApplicationContext(), "Anmeldung erfolgreich!", Toast.LENGTH_LONG).show();
  //andere Dinge mit dem erhaltenen JSONObject machen
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), "Fehler!", Toast.LENGTH_LONG).show();
               }
            }) {
                @Override
                public Map getHeaders() throws AuthFailureError {
                    Map pars = new HashMap();
                    pars.put("Content-Type", "application/x-www-form-urlencoded");
                    return pars;
                }

                @Override
                public Map getParams() throws AuthFailureError {
                    Map pars = new HashMap();
                    pars.put("Username", "usr");
                    pars.put("Password", "passwd");
                    pars.put("grant_type", "password");
                    return pars;
                }
            };
  //zur Anforderungs-Warteschlange hinzufügen
  requestqueue.AddToRequestQueue(stringReq);

3voto

Akeshwar Jha Punkte 4368

Ich habe es auf folgende Weise gemacht (der Inhaltstyp meines Anforderungsbodens war application/x-www-form-urlencoded):

Ich habe an den entsprechenden Stellen im Code Kommentare hinzugefügt.

/**
     * @param url - Endpunkt-URL des Aufrufs
     * @param requestBody - Ich empfange es als json, ohne irgendwelche Codierung von den entsprechenden Aktivitäten.
     * @param listener - StringRequestListener ist ein Interface, das ich erstellt habe, um die Ergebnisse in den entsprechenden Aktivitäten zu bearbeiten
     * @param activity - nur für den Kontext, überspringbar.
     * @param header - Dies enthält meinen x-api-key
     */
    public void makePostRequest2(String url, final JSONObject requestBody, final StringRequestListener listener,
                                 Activity activity, final Map header) {

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

        /**
         * Sie können diese Netzwerkprüfung überspringen.
         */
        if(!NetworkTester.isNetworkAvailable()) {
            Toast.makeText(MyApplication.getAppContext(),"Netzwerkfehler",Toast.LENGTH_SHORT).show();
            return;
        }

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                listener.onResponse(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onError(error);
            }
        }) {
            /**
             * Das Setzen des Body-Content-Typs ist der wichtigste Teil.
             * @return
             * Sie müssen diese Methode nicht schreiben, wenn Ihr Body-Content-Typ application/x-www-form-urlencoded ist und die Codierung charset=UTF-8 ist
             * Weil die Basismethode genau dasselbe tut.
             */
//            @Override
//            public String getBodyContentType() {
//                return "application/x-www-form-urlencoded; charset=UTF-8";
//            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                return header;
            }

            /**
             * Ich habe den Stil dieser Methode aus der Originalmethode von com.Android.Volley.Request kopiert.
             * @return
             * @throws AuthFailureError
             */
            @Override
            public byte[] getBody() throws AuthFailureError {

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

                //Ja, ich habe das von der Basismethode kopiert.
                if (params != null && params.size() > 0) {
                    return encodeParameters(params, getParamsEncoding());
                }
                return null;

            }

        };

        queue.add(stringRequest);

    }

    /**
     * Diese Methode war privat in der com.Android.Volley.Request-Klasse. Ich musste sie hier kopieren, um meine Parameter zu codieren.
     * @param params
     * @param paramsEncoding
     * @return
     */
    private byte[] encodeParameters(Map params, String paramsEncoding) {
        StringBuilder encodedParams = new StringBuilder();
        try {
            for (Map.Entry 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("Codierung nicht unterstützt: " + paramsEncoding, uee);
        }
    }

2voto

shakrlabs.com Punkte 51

Volley fügt einen Content-Type-Header unmittelbar vor dem Absenden der Anfrage hinzu.

     /**
     * Gibt den Inhaltstyp des POST- oder PUT-Bodys zurück.
     */
     public String getBodyContentType() {
         return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();
      }

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

    public class CustomVolleyRequest extends StringRequest {
           ...

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

           ...
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X