Search in sources :

Example 1 with HttpHeaders

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("没有获取到缓存,或者缓存已经过期!"));
        }
    }
}
Also used : HttpHeaders(com.lzy.okgo.model.HttpHeaders) CacheMode(com.lzy.okgo.cache.CacheMode)

Example 2 with HttpHeaders

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);
            }
        }
    });
}
Also used : HttpHeaders(com.lzy.okgo.model.HttpHeaders) Request(okhttp3.Request) BaseRequest(com.lzy.okgo.request.BaseRequest) CacheMode(com.lzy.okgo.cache.CacheMode) IOException(java.io.IOException) OkGoException(com.lzy.okgo.exception.OkGoException) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) Response(com.lzy.okgo.model.Response) AbsCallbackWrapper(com.lzy.okgo.callback.AbsCallbackWrapper) SocketTimeoutException(java.net.SocketTimeoutException) RequestBody(okhttp3.RequestBody)

Example 3 with HttpHeaders

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);
            }
        }
    });
}
Also used : HttpHeaders(com.lzy.okgo.model.HttpHeaders) Request(okhttp3.Request) BaseRequest(com.lzy.okgo.request.BaseRequest) CacheMode(com.lzy.okgo.cache.CacheMode) IOException(java.io.IOException) OkGoException(com.lzy.okgo.exception.OkGoException) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) Response(com.lzy.okgo.model.Response) AbsCallbackWrapper(com.lzy.okgo.callback.AbsCallbackWrapper) SocketTimeoutException(java.net.SocketTimeoutException) RequestBody(okhttp3.RequestBody)

Example 4 with HttpHeaders

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("没有获取到缓存,或者缓存已经过期!"));
        }
    }
}
Also used : HttpHeaders(com.lzy.okgo.model.HttpHeaders) CacheMode(com.lzy.okgo.cache.CacheMode)

Example 5 with HttpHeaders

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;
}
Also used : HttpHeaders(com.lzy.okgo.model.HttpHeaders) StringTokenizer(java.util.StringTokenizer) CacheEntity(com.lzy.okgo.cache.CacheEntity)

Aggregations

HttpHeaders (com.lzy.okgo.model.HttpHeaders)14 CacheMode (com.lzy.okgo.cache.CacheMode)4 HttpParams (com.lzy.okgo.model.HttpParams)4 IOException (java.io.IOException)3 CacheEntity (com.lzy.okgo.cache.CacheEntity)2 AbsCallbackWrapper (com.lzy.okgo.callback.AbsCallbackWrapper)2 OkGoException (com.lzy.okgo.exception.OkGoException)2 Response (com.lzy.okgo.model.Response)2 BaseRequest (com.lzy.okgo.request.BaseRequest)2 SocketTimeoutException (java.net.SocketTimeoutException)2 StringTokenizer (java.util.StringTokenizer)2 Request (okhttp3.Request)2 RequestBody (okhttp3.RequestBody)2 ContentValues (android.content.ContentValues)1 CookieJarImpl (com.lzy.okgo.cookie.CookieJarImpl)1 DBCookieStore (com.lzy.okgo.cookie.store.DBCookieStore)1 PersistentCookieStore (com.lzy.okgo.cookie.store.PersistentCookieStore)1 HttpsUtils (com.lzy.okgo.https.HttpsUtils)1 HttpLoggingInterceptor (com.lzy.okgo.interceptor.HttpLoggingInterceptor)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1