在发布请求中发送表单urlencoded参数android volley
我想使用表单urlencoded参数创建POST JSONObjectRequest。我怎样才能做到这一点?我试过下面的代码,但无济于事。在发布请求中发送表单urlencoded参数android volley
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调用!我该如何解决它?
尝试使用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);
有一个在JsonObjectRequest
没有预先做好的构造函数,它接受后的参数,让你做你自己的构造
你必须同时分配您的地图已声明变量在您的构造函数中的该方法中,并且您还必须添加此方法
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return this.params;
}
_you必须同时指定你的在构造函数中映射到该方法中已经声明的变量_请解释! – user4071017 2014-09-23 16:38:23
@ user4071017好吧,您必须在您的Volley项目中修改文件“JsonObjectRequest.java”。添加代码'Map
@ user4071017对不起,您需要学习Java基础以继续。 – CQM 2014-09-23 18:19:45
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);
}
,你的身体必须是这样的“用户名= AA &密码= BB & [email protected]”
嗨,你能告诉我它的工作方式吗?因为我在这里面对上面的代码请求错误。 – 2017-05-26 07:05:58
亚特很长很长的斗争,找到了解决办法。您需要重写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);
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";
}
...
}
我做到了以下方式(内容类型我的请求体的是应用程序/ x-WWW的形式,进行了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);
}
}
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);
}
使用这个,如果你要送样 “应用/ 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());
}
}
你从哪里得到GsonUtils? – 2017-10-26 06:24:21
我建议使用改造,它是一个伟大的图书馆的android网络 – 2017-10-27 11:28:16
对不起,没有运气!仍然是400错误! – user4071017 2014-09-23 16:29:38
这意味着您所做的请求不正确。检查API文档和您发送的内容,并确保它是正确的。你可以发送你的请求与一些其他的东西,如邮递员或RESTClient,并告诉我结果? – mmlooloo 2014-09-23 16:40:13
一切工作与邮递员:( – user4071017 2014-09-23 16:45:38