发现问题
Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。
Volley本身是不支持cookie,但是既想使用volley又想在对服务器发起http请求时加上cookie,并从服务器给的响应中读取cookie。怎么办呢?
其实很简单,Volley提供了非常强的扩展机制,使得我们可以很轻松地定制出任意类型的Request。
定制JsonObjectGetRequest
该定制Request可用于Get一条JSON格式的数据,同时能向服务器发起http请求时加上cookie。
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
/*
* Volley Get类型 可以发送Cookie
* */
public class JsonObjectGetRequest extends Request<JSONObject> {
private Response.Listener<JSONObject> mListener;
// 保存cookie
public String cookieFromResponse;
private Map<String, String> sendHeader = new HashMap<String, String>();
public JsonObjectGetRequest(String url,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener) {
super(Request.Method.GET, url, errorListener);
mListener = listener;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
// 防止中文乱码
@SuppressWarnings("deprecation")
String jsonString = new String(response.data, HTTP.UTF_8);
// 将cookie字符串添加到jsonObject中,该jsonObject会被deliverResponse递交,调用请求时则能在onResponse中得到
JSONObject jsonObject = new JSONObject(jsonString);
Log.w("json", "jsonObject " + jsonObject.toString());
return Response.success(jsonObject,
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);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return sendHeader;
}
public void setSendCookie(String cookie) {
sendHeader.put("Cookie", cookie);
}
}
使用方法
JsonObjectGetRequest get = new JsonObjectGetRequest(Url.api,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
try {
//TODO 响应操作
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//TODO 响应操作
Log.e("HTTP_get", error.getMessage(), error);
}
});
// 向服务器发起post请求时加上cookie字段
get.setSendCookie(customer.getCookie());
mQueue.add(get);
定制JsonObjectPostRequest
该定制Request可用于Post一条JSON格式的数据,同时能向服务器发起http请求时加上cookie,并从服务器给的响应中读取cookie。
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import android.util.Log;
/**
* Volley Post类型 可以接受和发送Cookie
*/
public class JsonObjectPostRequest extends Request<JSONObject> {
private Map<String, String> mMap;
private Response.Listener<JSONObject> mListener;
// 保存cookie
public String cookieFromResponse;
private Map<String, String> sendHeader = new HashMap<String, String>();
public JsonObjectPostRequest(String url,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener, Map<String, String> map) {
super(Request.Method.POST, url, errorListener);
mListener = listener;
mMap = map;
}
// 当http请求是post时,则需要该使用该函数设置往里面添加的键值对
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return mMap;
}
// 重写方法,处理cookie
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
// 防止中文乱码
@SuppressWarnings("deprecation")
String jsonString = new String(response.data, HTTP.UTF_8);
// 将cookie字符串添加到jsonObject中,该jsonObject会被deliverResponse递交,调用请求时则能在onResponse中得到
JSONObject jsonObject = new JSONObject(jsonString);
// 获取cookie字段
sendHeader = response.headers;
// 如果因为一些原因没有返回cookie的判断
if (sendHeader.get("Set-Cookie") != null) {
cookieFromResponse = sendHeader.get("Set-Cookie");
cookieFromResponse = cookieFromResponse.replace("\n", ";");
Log.w("cookie", cookieFromResponse);
jsonObject.put("Cookie", cookieFromResponse);
}
Log.w("json", "jsonObject " + jsonObject.toString());
return Response.success(jsonObject,
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);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return sendHeader;
}
public void setSendCookie(String cookie) {
sendHeader.put("Cookie", cookie);
}
}
使用方法
//json格式的数据
HashMap<String, String> urlParams = new HashMap<String, String>();
urlParams.put("phone", user.getText().toString());
urlParams.put("password", psw.getText().toString());
JsonObjectPostRequest post = new JsonObjectPostRequest(Url.api,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
try {
//TODO 响应操作
//保存Cookie
customer.setCookie(jsonObject.getString("Cookie"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//TODO 响应操作
Log.e("HTTP_login", error.getMessage(), error);
}
}, urlParams);
//判断是否有Cookie
if (!user.getCookie().equals("")) {
// 向服务器发起post请求时加上cookie字段
post.setSendCookie(user.getCookie());
}
mQueue.add(post);