對(duì)于volley的對(duì)象傳輸,在開(kāi)發(fā)過(guò)程中我們很多時(shí)候期望,傳輸能夠直接傳輸對(duì)象,而服務(wù)器端也接受到對(duì)象,那么多開(kāi)發(fā)對(duì)對(duì)于安卓的網(wǎng)絡(luò),我們選擇對(duì)其的對(duì)象傳輸進(jìn)行封裝,保證我們傳輸?shù)膶?duì)象與接受的對(duì)象能夠封裝完成好,不用進(jìn)行多余的JSON解析。Volley 的具體配置就不多贅述了。
1.定義一個(gè)JsonData 類,這個(gè)類是保證與服務(wù)器傳輸?shù)臅r(shí)候,先交互的實(shí)體類
public class JsonDataimplements Serializable {
/**
* 數(shù)據(jù)交換
*/
private static final long serialVersionUID = 8287262158680054979L;
//服務(wù)器狀態(tài)碼
private String code;
//服務(wù)器返回信息
private String msg;
//返回對(duì)象
private T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public? String toString(){
return? code+":"+msg+":"+data;
}
}
2.定義一個(gè)RequestUtils ,在其內(nèi)部定義一個(gè)私有的類,并重新其不封的方法,并設(shè)置其http headers并保持與服務(wù)器端一直,如果不知道服務(wù)器端的headers ,請(qǐng)利用瀏覽器的調(diào)試模式查看自己設(shè)置的headers
private class mJsonRequest extends JsonObjectRequest? {? ? ? ? /**? ? ? ? *
?@Override? ? ? ??
protected ResponseparseNetworkResponse(NetworkResponse response) {? ? ??
? ? ? try {? ?
?? ? ? ? ? ? response.headers.put("HTTP.CONTENT_TYPE", "utf-8");//
? ? ? ? ? ? ? ? String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));? ??
? ? ? ? ? ? String jsonString = new String(response.data,"utf-8");? ? ?
?? ? ? ? ? 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));? ?
?? ? ? ? }?
?? ? ? }??
? ? ? /**? ? ? ? * @param method? ? ? ? * @param url? ? ? ? * @param listener? ? ? ? * @param errorListener? ? ? ? */? ?
?? ? public mJsonRequest(int method, String url, RequestParams params, Listener listener, ? ? ? ? ? ErrorListener errorListener) {? ??
? ? ? ? ?super(method, url, params.toString(), listener, errorListener);? ??
? ? }? ? ?
?? @Override? ??
? ? public MapgetHeaders() throws AuthFailureError? ? ? ? {? ? ?
?? ? ? Mapheaders = new HashMap();
? ? ?headers.put("Accept", "application/json");
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
return headers;
}
@Override
public RetryPolicy getRetryPolicy()
{
RetryPolicy retryPolicy = new DefaultRetryPolicy(30 * 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
return retryPolicy;
}
@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=" + this.getParamsEncoding();
}
}
}
3.在RequestUtlis中寫上一個(gè)通用的post傳輸方式(get 方式可以自己去完善),添加上一般的網(wǎng)絡(luò)請(qǐng)求失敗的狀態(tài)值。
/**
*
Description:{HTTP POST方法}
*
*@paramurl
*@param
*@paramctx
*@paramrl
*/
publicvoidvolleyPost(String url, RequestParams param,finalContext ctx,finalMResponseListener rl,finalClass type)? {
if(!NetUtils.isConnected(ctx)) {
Toast.makeText(ctx,"網(wǎng)絡(luò)無(wú)法連接,請(qǐng)檢測(cè)您的網(wǎng)絡(luò)環(huán)境", Toast.LENGTH_SHORT).show();
rl.onErrorResponse(null);
return;
}
if(TextUtils.isEmpty(url))
return;
if(TextUtils.isEmpty(url))
return;
String murl =newString(url);
JsonObjectRequestrequest=null;
request=newmJsonRequest(Request.Method.POST, murl, param,newResponse.Listener() {
@Override
public voidonResponse(JSONObject response) {
JsonData data=? UtilText.JsonToVo(response,ctx, JsonData.class);
if(!Common.isNull(data)) {
data.setData(UtilText.JsonoVo(data.getData().toString(),ctx,type));
}
rl.onResponse(data);
}
},newResponse.ErrorListener() {
@Override
public voidonErrorResponse(VolleyError volleyerror) {
Log.e("VolleyRequest", volleyerror.toString());
if(volleyerror.getMessage() !=null)
volleyerror.printStackTrace();
NetworkResponse networkResponse = volleyerror.networkResponse;
if(networkResponse !=null) {
intstatusCode = networkResponse.statusCode;
if(statusCode ==404) {
Toast.makeText(ctx,"網(wǎng)絡(luò)資源沒(méi)有找到", Toast.LENGTH_SHORT).show();
}
// When Http response code is '500'
else if(statusCode ==500) {
Toast.makeText(ctx,"服務(wù)器繁忙,請(qǐng)稍后重試", Toast.LENGTH_SHORT).show();
}
// When Http response code other than 404, 500
else{
Toast.makeText(ctx,"無(wú)法連接到服務(wù)器,請(qǐng)稍后重試", Toast.LENGTH_SHORT).show();
}
}
else{
Toast.makeText(ctx,"無(wú)法連接到服務(wù)器,請(qǐng)稍后重試", Toast.LENGTH_SHORT).show();
}
rl.onErrorResponse(volleyerror);
}
});
request.setRetryPolicy(newDefaultRetryPolicy(30*1000,1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
String urls=request.getUrl();
Map headers=null;
try{
headers=request.getHeaders();
}catch(AuthFailureError authFailureError) {
authFailureError.printStackTrace();
}
String cacheKey =request.getCacheKey();
String bodyContentType=request.getBodyContentType();
ApplicationBase.addToRequestQueue(request);
}
當(dāng)然在post傳輸中,我們傳入的參數(shù)值是以requestParam的方式傳入,當(dāng)然在這傳輸?shù)臅r(shí)候我們可以適當(dāng)添加一些,自己APP特有的參數(shù),或者常有必備的參數(shù),如登錄的SID(服務(wù)器端通過(guò)攔截器來(lái)判斷是否有效),時(shí)間戳(騙過(guò)緩存,攔截器做一些適當(dāng)判斷,請(qǐng)求時(shí)間偏差大于多少就不判斷),APPKEY(是否是正常的請(qǐng)求設(shè)備)等。
4.編寫一個(gè)通用的方法,將類轉(zhuǎn)換為requestparam,利用反射
/****
* 將實(shí)體轉(zhuǎn)換為requestparam
* */
publicRequestParams? getMapParams(Object obj,String name) {
Class clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
if(fields ==null|| fields.length==0) {
returnparams;
}
try{
for(Field field : fields) {
field.setAccessible(true);
Object temp=field.get(obj);
if(Common.isNull(temp)) {
continue;
}
if( tempinstanceofInteger||tempinstanceofString||
tempinstanceofBoolean|| tempinstanceofFloat ||
tempinstanceofLong|| tempinstanceofDouble ||
tempinstanceofShort|| tempinstanceofByte){
if(name!=null){
params.put(name+"."+field.getName(), String.valueOf(temp));
}else{
params.put(field.getName(), String.valueOf(temp));
}
continue;
}else if(tempinstanceofArrayList){
List list=(List)temp;
for(inti=0;i
getMapParams(list.get(i),field.getName()+"["+i+"]");
}
}else if(tempinstanceofArrayMap){
}else{
getMapParams(temp,field.getName());
}
}
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}
return params;
}
因?yàn)樵诜?wù)器端,采用的springmvc 所以目前的傳輸方式只采用以上的幾種方式。
5.接下來(lái)就是測(cè)試以上的寫法
String url="http://desktop-3bmhc3j:8080/springmvc/user/test1";
User user=newUser();
user.setName("張三");
user.setPassword("密碼");
user.setId(123);
Menu menu=newMenu();
menu.setId(321);
List list=newArrayList<>();
list.add(menu);
menu.setId(2);
list.add(menu);
list.add(newMenu());
user.setMenu(menu);
user.setMenuList(list);
RequestUtil.getInstance().volleyPost(url, MapUtils.getInstance().getMapParams(user,null),this,newRequestUtil.MResponseListener() {
public voidonResponse(JsonData json){
Toast.makeText(OnLandAty.this, json.toString() ,Toast.LENGTH_LONG).show();
};
public voidonErrorResponse(VolleyError volleyError){
};
}, User.class);
}
在服務(wù)器端我是直接返回傳輸對(duì)象,而返回的也是User對(duì)象
最后一點(diǎn)就,我們可能會(huì)用Gson轉(zhuǎn)換對(duì)象.