前言:android端与PC端有时候都需要使用Cookie,但是两者在使用的时候还是存在一定的区别的。对于PC端而言,每次发起网络访问,使用的Cookie值都是不一样的,而在android端,Cookie值要求一致,这样在服务器端接收到提交过去的Cookie值时,才能正确识别,从而完成正常的一次网络请求。
实现方式:(基于okhttp)
1.首先,在第一次访问服务器时,Cookie值为空,则需要在返回的响应信息的header中获取到Cookie值;
2.之后,将Cookie值进行存储在内存中(一般推荐存在内存,不推荐存储在本地,主要是考虑到当Cookie值失效之后,再进行更新的方便);
3.当第一次请求得到Cookie值之后,在发起网络请求时,添加到header中即可。
private String doPost_Ok(String url, Object jsonForParam ){
String requestBody1 = null;
String contentType = null;
RequestBody requestBody=null;
if(jsonForParam instanceof String) {
System.out.println("提交参数形式 text============================> contentType = CONTENT_TYPE_TEXT;");
requestBody1 = (String)jsonForParam;
contentType = CONTENT_TYPE_TEXT;
MediaType mediaType = MediaType.parse(contentType);
requestBody = RequestBody.create(mediaType, requestBody1);
} else {
System.out.println("提交参数形式 json============================> contentType = CONTENT_TYPE_JSON");
contentType = CONTENT_TYPE_JSON;
requestBody1 = jsonForParam == null ? EMPTY_DATA : (JSON.toJSONString(jsonForParam));
MediaType JSON = MediaType.parse(contentType);
requestBody = RequestBody.create(JSON, com.alibaba.fastjson.JSON.toJSONString(requestBody1));
}
//创建一个请求对象
Request request;
if (JSESSIONID==null){
//第一次握手,请求体中不包含session值
request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
}
else {
request = new Request.Builder()
.url(url)
.addHeader("Cookie",JSESSIONID)
.post(requestBody)
.build();
}
//发送请求获取响应
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()){
if (JSESSIONID==null){
//当 JSESSIONID为空,表示是第一次握手,需要从response中获取header,从而得到session
String header = response.header("Set-Cookie");
System.out.println("header======================>"+header);
//保存session,以后都使用同一个session,服务器端才能识别
JSESSIONID=header.substring(0, header.indexOf(";"));
System.out.println("JSESSIONID======================>"+JSESSIONID);
}
body=response.body().string();
//当通过 EncryptClient 对象发起网络请求时,其模式即为 ENCRYPT(公私钥加密模式,这样请求和返回的数据都经过加密处理)时,
// 需要对返回的数据进行解密
if(OpenClient.this.requestMode == RequestMode.ENCRYPT) {
body = AESUtil.decryptFromHex(body, SdkContext.getRandomKey());
System.out.println("网络请求模式为 ENCRYPT=====================>对返回结果进行解密");
}
System.out.println("最后返回的结果 body======================>"+body);
}
} catch (Throwable e) {
e.printStackTrace();
}
//握手之后,执行网络请求,当返回"ssl交互出错"的结果时,需要重新进行握手
return body;
}