use of com.lzy.okgo.model.HttpHeaders in project okhttp-OkGo by jeasonlzy.
the class CacheCall method sendFailResultCallback.
/** 失败回调,发送到主线程 */
@SuppressWarnings("unchecked")
private void sendFailResultCallback(final boolean isFromCache, final okhttp3.Call call, final okhttp3.Response response, final Exception e) {
final CacheMode cacheMode = baseRequest.getCacheMode();
OkGo.getInstance().getDelivery().post(new Runnable() {
@Override
public void run() {
if (isFromCache) {
//缓存失败回调 (UI线程)
mCallback.onCacheError(call, e);
if (cacheMode == CacheMode.DEFAULT || cacheMode == CacheMode.REQUEST_FAILED_READ_CACHE) {
//请求结束回调 (UI线程)
mCallback.onAfter(null, e);
}
} else {
//请求失败回调 (UI线程)
mCallback.onError(call, response, e);
if (cacheMode != CacheMode.REQUEST_FAILED_READ_CACHE) {
//请求结束回调 (UI线程)
mCallback.onAfter(null, e);
}
}
}
});
//不同的缓存模式,可能会导致该失败进入两次,一次缓存失败,一次网络请求失败
if (!isFromCache && cacheMode == CacheMode.REQUEST_FAILED_READ_CACHE) {
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
//由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, call, response);
}
} else {
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
}
}
use of com.lzy.okgo.model.HttpHeaders in project okhttp-OkGo by jeasonlzy.
the class CacheCall method execute.
@Override
public void execute(AbsCallback<T> callback) {
synchronized (this) {
if (executed)
throw new IllegalStateException("Already executed.");
executed = true;
}
mCallback = callback;
if (mCallback == null)
mCallback = new AbsCallbackWrapper<>();
//请求执行前UI线程调用
mCallback.onBefore(baseRequest);
//请求之前获取缓存信息,添加缓存头和其他的公共头
if (baseRequest.getCacheKey() == null)
baseRequest.setCacheKey(HttpUtils.createUrlFromParams(baseRequest.getBaseUrl(), baseRequest.getParams().urlParamsMap));
if (baseRequest.getCacheMode() == null)
baseRequest.setCacheMode(CacheMode.NO_CACHE);
//无缓存模式,不需要进入缓存逻辑
final CacheMode cacheMode = baseRequest.getCacheMode();
if (cacheMode != CacheMode.NO_CACHE) {
//noinspection unchecked
cacheEntity = (CacheEntity<T>) CacheManager.INSTANCE.get(baseRequest.getCacheKey());
//检查缓存的有效时间,判断缓存是否已经过期
if (cacheEntity != null && cacheEntity.checkExpire(cacheMode, baseRequest.getCacheTime(), System.currentTimeMillis())) {
cacheEntity.setExpire(true);
}
HeaderParser.addCacheHeaders(baseRequest, cacheEntity, cacheMode);
}
//构建请求
RequestBody requestBody = baseRequest.generateRequestBody();
final Request request = baseRequest.generateRequest(baseRequest.wrapRequestBody(requestBody));
rawCall = baseRequest.generateCall(request);
if (cacheMode == CacheMode.IF_NONE_CACHE_REQUEST) {
//如果没有缓存,或者缓存过期,就请求网络,否者直接使用缓存
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
//由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, rawCall, null);
//获取缓存成功,不请求网络
return;
}
} else {
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
} else if (cacheMode == CacheMode.FIRST_CACHE_THEN_REQUEST) {
//先使用缓存,不管是否存在,仍然请求网络
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
//由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, rawCall, null);
}
} else {
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
}
if (canceled) {
rawCall.cancel();
}
currentRetryCount = 0;
rawCall.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
if (e instanceof SocketTimeoutException && currentRetryCount < baseRequest.getRetryCount()) {
//超时重试处理
currentRetryCount++;
okhttp3.Call newCall = baseRequest.generateCall(call.request());
newCall.enqueue(this);
} else {
mCallback.parseError(call, e);
//请求失败,一般为url地址错误,网络错误等,并且过滤用户主动取消的网络请求
if (!call.isCanceled()) {
sendFailResultCallback(false, call, null, e);
}
}
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
int responseCode = response.code();
//304缓存数据
if (responseCode == 304 && cacheMode == CacheMode.DEFAULT) {
if (cacheEntity == null) {
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("服务器响应码304,但是客户端没有缓存!"));
} else {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
//由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, call, response);
}
}
return;
}
//响应失败,一般为服务器内部错误,或者找不到页面等
if (responseCode == 404 || responseCode >= 500) {
sendFailResultCallback(false, call, response, OkGoException.INSTANCE("服务器数据异常!"));
return;
}
try {
Response<T> parseResponse = parseResponse(response);
T data = parseResponse.body();
//网络请求成功,保存缓存数据
handleCache(response.headers(), data);
//网络请求成功回调
sendSuccessResultCallback(false, data, call, response);
} catch (Exception e) {
//一般为服务器响应成功,但是数据解析错误
sendFailResultCallback(false, call, response, e);
}
}
});
}
use of com.lzy.okgo.model.HttpHeaders in project BaseProject by feer921.
the class CacheCall method execute.
@Override
public void execute(AbsCallback<T> callback) {
synchronized (this) {
if (executed)
throw new IllegalStateException("Already executed.");
executed = true;
}
mCallback = callback;
if (mCallback == null)
mCallback = new AbsCallbackWrapper<>();
// 请求执行前UI线程调用
mCallback.onBefore(baseRequest);
// 请求之前获取缓存信息,添加缓存头和其他的公共头
if (baseRequest.getCacheKey() == null)
baseRequest.setCacheKey(HttpUtils.createUrlFromParams(baseRequest.getBaseUrl(), baseRequest.getParams().urlParamsMap));
if (baseRequest.getCacheMode() == null)
baseRequest.setCacheMode(CacheMode.NO_CACHE);
// 无缓存模式,不需要进入缓存逻辑
final CacheMode cacheMode = baseRequest.getCacheMode();
if (cacheMode != CacheMode.NO_CACHE) {
// noinspection unchecked
cacheEntity = (CacheEntity<T>) CacheManager.INSTANCE.get(baseRequest.getCacheKey());
// 检查缓存的有效时间,判断缓存是否已经过期
if (cacheEntity != null && cacheEntity.checkExpire(cacheMode, baseRequest.getCacheTime(), System.currentTimeMillis())) {
cacheEntity.setExpire(true);
}
HeaderParser.addCacheHeaders(baseRequest, cacheEntity, cacheMode);
}
// 构建请求
RequestBody requestBody = baseRequest.generateRequestBody();
final Request request = baseRequest.generateRequest(baseRequest.wrapRequestBody(requestBody));
rawCall = baseRequest.generateCall(request);
if (cacheMode == CacheMode.IF_NONE_CACHE_REQUEST) {
// 如果没有缓存,或者缓存过期,就请求网络,否者直接使用缓存
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
// 由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, rawCall, null);
// 获取缓存成功,不请求网络
return;
}
} else {
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
} else if (cacheMode == CacheMode.FIRST_CACHE_THEN_REQUEST) {
// 先使用缓存,不管是否存在,仍然请求网络
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
// 由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, rawCall, null);
}
} else {
sendFailResultCallback(true, rawCall, null, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
}
if (canceled) {
rawCall.cancel();
}
currentRetryCount = 0;
rawCall.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
if (e instanceof SocketTimeoutException && currentRetryCount < baseRequest.getRetryCount()) {
// 超时重试处理
currentRetryCount++;
okhttp3.Call newCall = baseRequest.generateCall(call.request());
newCall.enqueue(this);
} else {
mCallback.parseError(call, e);
// 请求失败,一般为url地址错误,网络错误等,并且过滤用户主动取消的网络请求
if (!call.isCanceled()) {
sendFailResultCallback(false, call, null, e);
}
}
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
int responseCode = response.code();
// 304缓存数据
if (responseCode == 304 && cacheMode == CacheMode.DEFAULT) {
if (cacheEntity == null) {
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("服务器响应码304,但是客户端没有缓存!"));
} else {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
// 由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, call, response);
}
}
return;
}
// 响应失败,一般为服务器内部错误,或者找不到页面等
if (responseCode == 404 || responseCode >= 500) {
sendFailResultCallback(false, call, response, OkGoException.INSTANCE("服务器数据异常!"));
return;
}
try {
Response<T> parseResponse = parseResponse(response);
T data = parseResponse.body();
// 网络请求成功,保存缓存数据
handleCache(response.headers(), data);
// 网络请求成功回调
sendSuccessResultCallback(false, data, call, response);
} catch (Exception e) {
// 一般为服务器响应成功,但是数据解析错误
sendFailResultCallback(false, call, response, e);
}
}
});
}
use of com.lzy.okgo.model.HttpHeaders in project BaseProject by feer921.
the class CacheCall method sendFailResultCallback.
/**
* 失败回调,发送到主线程
*/
@SuppressWarnings("unchecked")
private void sendFailResultCallback(final boolean isFromCache, final okhttp3.Call call, final okhttp3.Response response, final Exception e) {
final CacheMode cacheMode = baseRequest.getCacheMode();
OkGo.getInstance().getDelivery().post(new Runnable() {
@Override
public void run() {
if (isFromCache) {
// 缓存失败回调 (UI线程)
mCallback.onCacheError(call, e);
if (cacheMode == CacheMode.DEFAULT || cacheMode == CacheMode.REQUEST_FAILED_READ_CACHE) {
// 请求结束回调 (UI线程)
mCallback.onAfter(null, e);
}
} else {
// 请求失败回调 (UI线程)
mCallback.onError(call, response, e);
if (cacheMode != CacheMode.REQUEST_FAILED_READ_CACHE) {
// 请求结束回调 (UI线程)
mCallback.onAfter(null, e);
}
}
}
});
// 不同的缓存模式,可能会导致该失败进入两次,一次缓存失败,一次网络请求失败
if (!isFromCache && cacheMode == CacheMode.REQUEST_FAILED_READ_CACHE) {
if (cacheEntity != null && !cacheEntity.isExpire()) {
T data = cacheEntity.getData();
HttpHeaders headers = cacheEntity.getResponseHeaders();
if (data == null || headers == null) {
// 由于没有序列化等原因,可能导致数据为空
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
} else {
sendSuccessResultCallback(true, data, call, response);
}
} else {
sendFailResultCallback(true, call, response, OkGoException.INSTANCE("没有获取到缓存,或者缓存已经过期!"));
}
}
}
use of com.lzy.okgo.model.HttpHeaders in project BaseProject by feer921.
the class HeaderParser method createCacheEntity.
/**
* 根据请求结果生成对应的缓存实体类,以下为缓存相关的响应头
* Cache-Control: public 响应被缓存,并且在多用户间共享
* Cache-Control: private 响应只能作为私有缓存,不能在用户之间共享
* Cache-Control: no-cache 提醒浏览器要从服务器提取文档进行验证
* Cache-Control: no-store 绝对禁止缓存(用于机密,敏感文件)
* Cache-Control: max-age=60 60秒之后缓存过期(相对时间),优先级比Expires高
* Date: Mon, 19 Nov 2012 08:39:00 GMT 当前response发送的时间
* Expires: Mon, 19 Nov 2012 08:40:01 GMT 缓存过期的时间(绝对时间)
* Last-Modified: Mon, 19 Nov 2012 08:38:01 GMT 服务器端文件的最后修改时间
* ETag: "20b1add7ec1cd1:0" 服务器端文件的ETag值
* 如果同时存在cache-control和Expires,浏览器总是优先使用cache-control
*
* @param responseHeaders 返回数据中的响应头
* @param data 解析出来的数据
* @param cacheMode 缓存的模式
* @param cacheKey 缓存的key
* @return 缓存的实体类
*/
public static <T> CacheEntity<T> createCacheEntity(Headers responseHeaders, T data, CacheMode cacheMode, String cacheKey) {
// 缓存相对于本地的到期时间
long localExpire = 0;
if (cacheMode == CacheMode.DEFAULT) {
long date = HttpHeaders.getDate(responseHeaders.get(HttpHeaders.HEAD_KEY_DATE));
long expires = HttpHeaders.getExpiration(responseHeaders.get(HttpHeaders.HEAD_KEY_EXPIRES));
String cacheControl = HttpHeaders.getCacheControl(responseHeaders.get(HttpHeaders.HEAD_KEY_CACHE_CONTROL), responseHeaders.get(HttpHeaders.HEAD_KEY_PRAGMA));
// 没有缓存头控制,不需要缓存
if (TextUtils.isEmpty(cacheControl) && expires <= 0)
return null;
long maxAge = 0;
if (!TextUtils.isEmpty(cacheControl)) {
StringTokenizer tokens = new StringTokenizer(cacheControl, ",");
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim().toLowerCase(Locale.getDefault());
if (token.equals("no-cache") || token.equals("no-store")) {
// 服务器指定不缓存
return null;
} else if (token.startsWith("max-age=")) {
try {
// 获取最大缓存时间
maxAge = Long.parseLong(token.substring(8));
// 服务器缓存设置立马过期,不缓存
if (maxAge <= 0)
return null;
} catch (Exception e) {
OkLogger.e(e);
}
}
}
}
// 获取基准缓存时间,优先使用response中的date头,如果没有就使用本地时间
long now = System.currentTimeMillis();
if (date > 0)
now = date;
if (maxAge > 0) {
// Http1.1 优先验证 Cache-Control 头
localExpire = now + maxAge * 1000;
} else if (expires >= 0) {
// Http1.0 验证 Expires 头
localExpire = expires;
}
} else {
localExpire = System.currentTimeMillis();
}
// 将response中所有的头存入 HttpHeaders,原因是写入数据库的对象需要实现序列化,而ok默认的Header没有序列化
HttpHeaders headers = new HttpHeaders();
for (String headerName : responseHeaders.names()) {
headers.put(headerName, responseHeaders.get(headerName));
}
// 构建缓存实体对象
CacheEntity<T> cacheEntity = new CacheEntity<>();
cacheEntity.setKey(cacheKey);
cacheEntity.setData(data);
cacheEntity.setLocalExpire(localExpire);
cacheEntity.setResponseHeaders(headers);
return cacheEntity;
}
Aggregations