Android Volley框架的幾種post提交請求方式和探究POST、GET提交
首先簡單描述一下Google的Android開發團隊在2013年推出的一個網路通訊框架Volley.它的設計目標是進行資料量不大,但通訊頻繁的網路操作,而對於大資料量的網路操作,比如下載檔案等,Volley的表現就不盡如人意。
在app開發中,我們最常見的就是從app客戶端向服務端發一個http請求.對於兩種基本的web請求方式get和post來說,get請求方式相對比較簡單,在此略過不表.本文重點描述一下通過volley進行幾種post提交的方式.
1.客戶端以普通的post方式進行提交,服務端返回字串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.POST,httpurl,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "response -> " + response);
}
}, new Response.ErrorListener() { @Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
}
}) {
@Override
protected Map<String, String> getParams() {
//在這裡設定需要post的引數
Map<String, String> map = new HashMap<String, String>();
map.put( "name1" , "value1" );
map.put( "name2" , "value2" );
return params;
}
};
requestQueue.add(stringRequest);
|
2.客戶端以json串的post請求方式進行提交,服務端返回json串
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
Map<String, String> map = new HashMap<String, String>();
map.put( "name1" , "value1" );
map.put( "name2" , "value2" );
JSONObject jsonObject = new JSONObject(params);
JsonRequest<JSONObject> jsonRequest = new JsonObjectRequest(Method.POST,httpurl, jsonObject,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(TAG, "response -> " + response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
}
})
{
//注意此處override的getParams()方法,在此處設定post需要提交的引數根本不起作用
//必須象上面那樣,構成JSONObject當做實參傳入JsonObjectRequest物件裡
//所以這個方法在此處是不需要的
// @Override
// protected Map<String, String> getParams() {
// Map<String, String> map = new HashMap<String, String>();
// map.put("name1", "value1");
// map.put("name2", "value2");
// return params;
// }
@Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put( "Accept" , "application/json" );
headers.put( "Content-Type" , "application/json; charset=UTF-8" );
return headers;
}
};
requestQueue.add(jsonRequest);
|
新版本寫法如下,和以上有所不同
@Override
public RequestInfo Create(String url , final RequestMethod method , final Map<String, Object> params , final IRequestCallBack<JSONObject> callBack)
{
if (TextUtils.isEmpty(url) || method == null)
{
return null;
}
final boolean isIcsonRequest = NetRequestUtils.isIcsonRequest(url);
// JSONObject jsonParams = new JSONObject(params);
JSONObject jsonObject = new JSONObject(params);
mRequestInfo = new RequestInfo();
JsonRequest<JSONObject> request = new JsonRequest(method.getValue(), url,jsonObject.toString(),new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject result)
{
if (result != null)
{
callBack.onResponse(mRequestInfo.getRequestToken(), result);
}
else
{
callBack.onError(mRequestInfo.getRequestToken(), ErrorMsgUtil.getCommNetDataErrorMsg());
}
}
}, new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError arg0)
{
ErrorMsg msg = new ErrorMsg();
if (arg0 != null && arg0.networkResponse != null)
{
ErrorDetail errorDetal = new ErrorDetail();
errorDetal.data = arg0.networkResponse.data;
errorDetal.headers = arg0.networkResponse.headers;
errorDetal.networkTimeMs = arg0.networkResponse.networkTimeMs;
errorDetal.notModified = arg0.networkResponse.notModified;
errorDetal.statusCode = arg0.networkResponse.statusCode;
msg.setErrorObject(errorDetal);
}
//TODO:設定通用的異常code msg.setErrorCode(errorCode);
callBack.onError(mRequestInfo.getRequestToken(), msg);
}
})
{
@Override
protected String getParamsEncoding()
{
return mRequestInfo.getRequestCharset();
}
@Override
protected String getPostParamsEncoding()
{
return super.getPostParamsEncoding();
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response)
{
String parsedStr;
try
{
byte[] ret = response.data;
if (response.headers.containsKey("Content-Encoding") && response.headers.get("Content-Encoding").equals("gzip"))
{
ByteArrayInputStream input = new ByteArrayInputStream(response.data);
ByteArrayOutputStream tmpOutput = new ByteArrayOutputStream(BUFFERSIZE);
GZIPInputStream gin = new GZIPInputStream(input);
int count;
byte data[] = new byte[BUFFERSIZE];
while ((count = gin.read(data, 0, BUFFERSIZE)) != -1)
{
tmpOutput.write(data, 0, count);
}
gin.close();
ret = tmpOutput.toByteArray();
}
if (TextUtils.isEmpty(mRequestInfo.getResponseCharset()))
{
String chartSet = HttpHeaderParser.parseCharset(response.headers);
parsedStr = new String(ret, chartSet);
}
else
{
parsedStr = new String(response.data, mRequestInfo.getResponseCharset());
}
}
catch (UnsupportedEncodingException e)
{
parsedStr = new String(response.data);
}
catch (IOException e)
{
e.printStackTrace();
parsedStr = new String(response.data);
}
try {
return Response.success(new JSONObject(parsedStr), HttpHeaderParser.parseCacheHeaders(response));
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError
{
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json; charset=UTF-8");
return headers;
}
};
看了上面這段程式碼,會覺得volley這個框架實在是還不夠完善,使用JsonObjectRequest物件提交一個post請求,如果有引數需要提交,就必須以JSONObject的json串方式提交.
如果服務端並不支援這種方式呢?比如常見的spring mvc服務端,就很難支援json的請求方式.
那麼我們想實現這個目標,就需要使用下面給出的辦法.
3.客戶端以普通的post方式進行提交,服務端返回json串
首先在Activity類裡,繼承Request實現一個NormalPostRequest類
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
private class NormalPostRequest extends Request<JSONObject> {
private Map<String, String> mMap;
private Listener<JSONObject> mListener;
public NormalPostRequest(String url, Listener<JSONObject> listener,ErrorListener errorListener, Map<String, String> map) {
super (Request.Method.POST, url, errorListener);
mListener = listener;
mMap = map;
}
//mMap是已經按照前面的方式,設定了引數的例項
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return mMap;
}
//此處因為response返回值需要json資料,和JsonObjectRequest類一樣即可
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,HttpHeaderParser.parseCharset(response.headers));
return Response.success( new JSONObject(jsonString),HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error( new ParseError(e));
} catch (JSONException je) {
return Response.error( new ParseError(je));
}
}
@Override
protected void deliverResponse(JSONObject response) {
mListener.onResponse(response);
}
}
|
接下來的呼叫方式和前面差不多,生成一個Request例項,加入佇列中即可.
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
Request<JSONObject> request = new NormalPostRequest(httpurl,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d(TAG, "response -> " + response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
}
}, params);
requestQueue.add(request);
|
以上程式碼在android 4.3環境下測試通過.
2、請求報頭
請求報頭允許客戶端向伺服器端傳遞請求的附加資訊以及客戶端自身的資訊。
常用的請求報頭
Accept
Accept請求報頭域用於指定客戶端接受哪些型別的資訊。eg:Accept:image/gif,表明客戶端希望接受GIF圖象格式的資源;Accept:text/html,表明客戶端希望接受html文字。http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html
分類: Linux
這個話題源於一次客戶端與伺服器互動的聯調。下面以java為例來說明。
首先要分清的是,在客戶端發起請求到伺服器端收到請求處理完畢返回資訊再到客戶端收到反饋,這中間經歷了哪些環節:
- 首先,客戶端構造了一個HttpRequest,裡面包含了需要提交到伺服器端的資料,客戶端提交該HtteRequest(比如通過HttpClient物件提交)。
- 接著,伺服器端收到此請求,在伺服器端對應的物件為HttpServletRequest
- 然後,伺服器端根據請求處理後,生成了一個HttpServletResponse,返回給客戶端
- 客戶端展現伺服器端返回的資料
清楚了這幾個環節,自然也就可以得知,我們熟悉的HttpServletRequest和HttpServletResponse是伺服器端的物件,而HttpRequest是客戶端的物件,切不可搞混。他們的Content-Type都遵循RFC2616中定義的規範,但對於不同的物件,他們的Content-Type是不同的,例如,對於HttpRequest/HttpServletRequest物件,在最常見的表單提交中,Content-Type通常是application/x-www-form-urlencoded或multipart/form-data,前者通常用於沒有附件上傳的表單,後者通常用於需要上傳附件的表單,詳閱;而HttpServletResponse的Content-Type通常是text/html、application/json等。
ok,理解清楚了資料互動的過程,也就不難理解他們的Content-Type為何不同了。
提交引數和返回都有相應的內容型別
譬如:要提交JSON引數,應該寫入的引數是JSON字串,content-type應該是json
地址:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html
以上內容來源:http://www.open-open.com/lib/view/open1407727047207.html
http://blog.itpub.net/29867/viewspace-692485/