web-dev-qa-db-ja.com

post-requestでform-urlencodedパラメータを送信Android volley

フォームurlencodedパラメーターを使用してPOST JSONObjectRequestを作成します。これを行うにはどうすればよいですか?次のコードを試しましたが、役に立ちませんでした。

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

API呼び出しで400件の悪いリクエストを受け取っています!どうすれば修正できますか?

35
user4071017

長い長い闘争の後、解決策を見つけました。 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);
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);
}

そして、あなたの体は次のようなものでなければなりません。「username=aa&password=bb&[email protected]

9
TheOne_su

以下のコードのように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);
5
mmlooloo

Volleyは、リクエストが送信される直前に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";
           }               

           ...
    }
2
shakrlabs.com

私はそれを次のように行いました(私のリクエストボディのコンテンツタイプは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);
        }
    }
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);
}

「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

JsonObjectRequestにはpostパラメーターを受け入れる事前作成されたコンストラクターがないため、独自のコンストラクターを作成しました

コンストラクタ内でそのメソッドで既に宣言されている変数にマップを割り当てる必要があり、このメソッドを追加する必要があります

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