這幾天幫網友解決volley請求的問題,才發現volley真的很難用。如果新項目就不要用volley網絡框架了。舊項目能換則換吧
第一種:Params方式
這個是最簡單的,就是Map。
PostJsonRequest
public class PostJsonRequest extends JsonObjectRequest implements INetToken {
private boolean needToken = true;
public static final int TYPE_API_QUGUANZHANG = 1;
public static final int TYPE_API_HUIJIEQIANBAO = 2;
private int type = TYPE_API_QUGUANZHANG;
private String productId = "1";
/**
* 構造函數,初始化請求對象
*/
public PostJsonRequest(String url, JSONObject params, Listener<JSONObject> listener,
ErrorListener errorListener) {
super(Method.POST, url, params, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(InterfaceConfig.SOCKET_TIMEOUT, InterfaceConfig.MAX_RETRIES, InterfaceConfig.BACK_OFF));
}
public PostJsonRequest(String url, JSONObject params, Listener<JSONObject> listener,
ErrorListener errorListener, int type, String productId) {
super(Method.POST, url, params, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(InterfaceConfig.SOCKET_TIMEOUT, InterfaceConfig.MAX_RETRIES, InterfaceConfig.BACK_OFF));
this.type = type;
this.productId = productId;
}
/**
* 重寫參數編碼方法
*/
@Override
protected String getParamsEncoding() {
return InterfaceConfig.ENCODEING;
}
/**
* 重寫請求頭獲取方法
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("version", String.valueOf(BuildConfig.VERSION_CODE));
headers.put("User-Agent", Constants.USER_AGENT());
return headers;
}
@Override
public void setNeedToken(boolean needToken) {
this.needToken = needToken;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
Response<JSONObject> superResponse = super.parseNetworkResponse(response);
String authToken = response.headers.get("x-auth-token");
if (CommonUtils.isNullOrEmpty(authToken)) {
authToken = response.headers.get("newAccessToken");
}
if (!CommonUtils.isNullOrEmpty(authToken)) {
HttpUtil.saveSession(authToken);
CommonUtils.LOG_D(getClass(), "authToken = " + HttpUtil.sessionId);
}
return superResponse;
}
}
調用地方:
public Request<JSONObject> doPostByJson(String url, JSONObject jsonObject,
RequestListener requestListener, boolean
isOpenProgressbar) {
Request<JSONObject> request = null;
try {
boolean needCache = jsonObject.optBoolean("needCache", false);
boolean readCache = jsonObject.optBoolean("readCache", false);
jsonObject.remove("needCache");
jsonObject.remove("readCache");
String md5 = createKey(jsonObject, url);
boolean netState = checkNetState();
// 網絡檢查
if (netState) {//有網絡
checkLocalCache(md5, requestListener, readCache);
} else {
checkLocalCache(md5, requestListener, needCache);
TooltipUtils.showToastL(app, app.getString(R.string.net_error_check));
return null;
}
if (isOpenProgressbar) {
requestListener.onReqStart();
}
CommonUtils.LOG_D(getClass(), "url = %s, params = %s", url, jsonObject.toString());
PostJsonRequest postJsonRequest = new PostJsonRequest(url, jsonObject,
new IMJsonListener(requestListener, context).setCacheKey(needCache ? md5 :
null),
new IMErrorListenr(requestListener));
ensureToken(jsonObject, postJsonRequest);
queue.cancelAll(new SameRequestFilter(md5));
request = queue.add(postJsonRequest);
// 爲請求添加context標記
request.setTag(context);
} catch (Exception e) {
e.printStackTrace();
requestListener.onError("創建連接錯誤");
requestListener.onReqFinish();
}
return request;
}
這裏就是key和value
private JSONObject initCommonParams(Map<String, Object> params) {
params.put("appVerison", BuildConfig.VERSION_NAME);
params.put("channel", App.channel);
JSONObject jsonObject = new JSONObject(params);
return jsonObject;
}
第二種:請求參數是List<String>
的json方式
文字不好表達,來看個postman模擬請求圖吧
你看圖不是key value結構,接口需要List<String>
的json數據
PostJsonRequest2
public class PostJsonRequest2 extends JsonRequest<JSONObject> implements INetToken {
private boolean needToken = true;
public static final int TYPE_API_QUGUANZHANG = 1;
public static final int TYPE_API_HUIJIEQIANBAO = 2;
private int type = TYPE_API_QUGUANZHANG;
private String productId = "1";
/**
* 構造函數,初始化請求對象
*/
public PostJsonRequest2(String url, JSONArray params, Listener<JSONObject> listener,
ErrorListener errorListener) {
super(Request.Method.POST, url, params.toString(), listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(InterfaceConfig.SOCKET_TIMEOUT, InterfaceConfig.MAX_RETRIES, InterfaceConfig.BACK_OFF));
}
public PostJsonRequest2(String url, JSONArray params, Listener<JSONObject> listener,
ErrorListener errorListener, int type, String productId) {
super(Method.POST, url, params.toString(), listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(InterfaceConfig.SOCKET_TIMEOUT, InterfaceConfig.MAX_RETRIES, InterfaceConfig.BACK_OFF));
this.type = type;
this.productId = productId;
}
/**
* 重寫參數編碼方法
*/
@Override
protected String getParamsEncoding() {
return InterfaceConfig.ENCODEING;
}
/**
* 重寫請求頭獲取方法
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Charsert", getParamsEncoding());
headers.put("User-Agent", Constants.USER_AGENT());
return headers;
}
@Override
public void setNeedToken(boolean needToken) {
this.needToken = needToken;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
Response<JSONObject> superResponse;
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
superResponse = Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
superResponse = Response.error(new ParseError(e));
} catch (JSONException je) {
superResponse = Response.error(new ParseError(je));
}
String authToken = response.headers.get("x-auth-token");
if (CommonUtils.isNullOrEmpty(authToken)) {
authToken = response.headers.get("newAccessToken");
}
if (!CommonUtils.isNullOrEmpty(authToken)) {
HttpUtil.saveSession(authToken);
CommonUtils.LOG_D(getClass(), "authToken = " + HttpUtil.sessionId);
}
return superResponse;
}
}
看到沒,構造方法中用了JSONArray
調用地方:
public Request<JSONObject> doPostByJson(String url, JSONArray jsonObject,
RequestListener requestListener, boolean
isOpenProgressbar) {
Request<JSONObject> request = null;
try {
if (isOpenProgressbar) {
requestListener.onReqStart();
}
PostJsonRequest2 postJsonRequest = new PostJsonRequest2(url, jsonObject,
new IMJsonListener(requestListener, context).setCacheKey(""),
new IMErrorListenr(requestListener));
request = queue.add(postJsonRequest);
// 爲請求添加context標記
request.setTag(context);
} catch (Exception e) {
e.printStackTrace();
requestListener.onError("創建連接錯誤");
requestListener.onReqFinish();
}
return request;
}
第三種:請求參數是用Body的key value方式
還是看張postman的請求圖
這種方式更麻煩點,還要改變傳輸類型
PostJsonRequest3
public class PostJsonRequest3 extends JsonRequest<JSONObject> implements INetToken {
private boolean needToken = true;
public static final int TYPE_API_QUGUANZHANG = 1;
public static final int TYPE_API_HUIJIEQIANBAO = 2;
private int type = TYPE_API_QUGUANZHANG;
private String productId = "1";
/**
* 構造函數,初始化請求對象
*/
public PostJsonRequest3(String url, String params, Listener<JSONObject> listener,
ErrorListener errorListener) {
super(Request.Method.POST, url, params, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(InterfaceConfig.SOCKET_TIMEOUT, InterfaceConfig.MAX_RETRIES, InterfaceConfig.BACK_OFF));
}
/**
* 重寫參數編碼方法
*/
@Override
protected String getParamsEncoding() {
return InterfaceConfig.ENCODEING;
}
/**
* 重寫請求頭獲取方法
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("appVerison", "4.0.9.deb");
headers.put("User-Agent", Constants.USER_AGENT());
headers.put("channel", "dev_XYH");
headers.put("accessToken", "0d5a0f5c-7673-47bf-994c-3ef79980a904");
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
@Override
public void setNeedToken(boolean needToken) {
this.needToken = needToken;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
Response<JSONObject> superResponse;
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
superResponse = Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
superResponse = Response.error(new ParseError(e));
} catch (JSONException je) {
superResponse = Response.error(new ParseError(je));
}
String authToken = response.headers.get("x-auth-token");
if (CommonUtils.isNullOrEmpty(authToken)) {
authToken = response.headers.get("newAccessToken");
}
if (!CommonUtils.isNullOrEmpty(authToken)) {
HttpUtil.saveSession(authToken);
CommonUtils.LOG_D(getClass(), "authToken = " + HttpUtil.sessionId);
}
return superResponse;
}
@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();
}
}
注意:構造方法的變化和getBodyContentType()
調用地方:
public Request<JSONObject> doPostByJson2(String url, Map<String, String> jsonObject,
RequestListener requestListener, boolean
isOpenProgressbar) {
Request<JSONObject> request = null;
try {
if (isOpenProgressbar) {
requestListener.onReqStart();
}
PostJsonRequest3 postJsonRequest = new PostJsonRequest3(url, appendParameter(url,jsonObject),
new IMJsonListener(requestListener, context).setCacheKey(
null),
new IMErrorListenr(requestListener));
request = queue.add(postJsonRequest);
// 爲請求添加context標記
request.setTag(context);
} catch (Exception e) {
e.printStackTrace();
requestListener.onError("創建連接錯誤");
requestListener.onReqFinish();
}
return request;
}
public String appendParameter(String url, Map<String,String> params){
Uri uri = Uri.parse(url);
Uri.Builder builder = uri.buildUpon();
for(Map.Entry<String,String> entry:params.entrySet()){
builder.appendQueryParameter(entry.getKey(),entry.getValue());
}
return builder.build().getQuery();
}