先看一下,Velloy村身爲我們提供了那些請求類型:
1.StringRequest,專門用來處理String類型的數據請求;
2.JsonObjectRequest和JsonArrayRequest,專門用來處理Json對象類型的數據請求
顯然,Velloy自帶的這幾請求類型並不是我們程序中最常用的,無論是返回JsonObject還是String,都需要我們二次處理爲對象類型,那麼可不可以有一個請求返回的直接就是我們需要的 Entity對象呢,當然是可以的,其次,Velloy爲我們提供的請求 都是無Cookie管理的,這顯然也是不 完整的.
基於以上兩點原因,我們自定義一個再Cookie管理的,直接返回Entity對象的Request.先看一下StringRequest類的源碼,源碼如下:
public class StringRequest extends Request<String> {
private final Listener<String> mListener;
public StringRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
}
源碼很簡單,我們需要注意的也就是parseNetworkResponse這個方法,它是處理服務器返回數據的核心方法,在StringRequest 類的處理中,就是拿到響應體的數據,再根據頭中的請求編碼格式,轉化爲一個字符串,所以我們只要在此方法中將返回 的數據轉化爲我們需要的對象類型既可.下面看代碼:
public class ObjectRequest extends Request<Object> {
//請求成功回調
private final Listener<Object> mListener;
//實體對象字節碼
private final Class<?> clazz;
//請求參數列表
private final HashMap<String, String> paramsMap;
public ObjectRequest(String url, HashMap<String, String> paramsMap,
Listener<Object> listener, ErrorListener errorListener,
Class<?> clazz) {
super(Method.POST, url, errorListener);
this.mListener = listener;
this.clazz = clazz;
this.paramsMap = paramsMap;
}
/**
* 添加請求頭部信息
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
//<span style="color:#FF0000;">如果Application中已經有了Cookie信息,帶Cookie請求.</span>
Map<String, String> map = new HashMap<String, String>();
if (VolleyApplication.getInstance().getCookie() != null) {
map.put("Cookie", VolleyApplication.getInstance().getCookie());
}
return super.getHeaders();
}
/**
* 添加請求參數方法
*/
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return paramsMap;
}
@Override
protected Response<Object> parseNetworkResponse(NetworkResponse response) {
for (String s : response.headers.keySet()) {
if (s.contains("Set-Cookie")) {
/**
*<span style="color:#FF0000;"> 保存到全局Cookie變量中,後續的請求直接取出使用</span>
*/
VolleyApplication.getInstance().setCookie(
response.headers.get(s));
break;
}
}
try {
String string = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
/<span style="color:#FF0000;">/將返回的Json字符串直接轉化爲對象</span>
return Response.success(
ResponseEntityToModule.parseJsonToModule(string, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(Object response) {
mListener.onResponse(response);
}
}
很簡單的我們就定製了一個直接返回對象並且處理了Cookie 的請求對象.下面看如何使用它去請求服務器.
1.Activity中代碼:
public class MainActivity extends Activity implements Listener<Object>,
ErrorListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RequestCenter.getInstance().userLogin("focusgbbuyer", "focus1234",
this, this);
}
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
@Override
public void onResponse(Object response) {
Log.e("Response", "Session:"+((User) response).sessionid + "\r\nCookie:"
+ VolleyApplication.getInstance().getCookie());
}
}
2.RequestCenter中是所有請求的集合:
public class RequestCenter {
private static RequestCenter instance = null;
private RequestQueue mQueue;
private VolleyApplication application;
private RequestCenter() {
application = VolleyApplication.getInstance();
mQueue = application.getRequestQueue();
}
public static RequestCenter getInstance() {
if (instance == null) {
synchronized (RequestCenter.class) {
if (instance == null) {
instance = new RequestCenter();
}
}
}
return instance;
}
/**
* 用戶登錄請求
*
* @param username
* 用戶名
* @param password
* 密碼
* @param context
* @param lisener
* 登錄結果回調
*/
public void userLogin(String username, String password,
Listener<Object> listener, ErrorListener errorListener) {
HashMap<String, String> params = new HashMap<String, String>();
params.put("loginId", username);
params.put("password", password);
params.put("region", "MIC for Buyer Android");
ObjectRequest stringRequest = new ObjectRequest(
UrlConstants.USER_LOGIN, params, listener, errorListener,
User.class);
mQueue.add(stringRequest);
}
}
使用單例確保這些大對象,只有一個實例既可.經過這樣一封裝,使用起來很簡單了.下面看服務器的返回數據.
好了,完全符合我們的要求,有新需求還可以在上面直接修改,下面是Demp源碼: