当在排序中实现缓存时,防止Volley在POST请求方法上发送缓存参数

时间:2016-03-29 15:22:57

标签: android caching android-volley

我希望凌空能够缓存从服务器获取的响应。因此,我已经实现了缓存代码(ParseNetworkResponse)。但是,当发出POST请求时,volley会发送缓存参数。如何防止凌空这样做?最好如何修改下面的缓存代码以停止缓存POST参数?我只希望缓存来自服务器的响应。

        public NetworkConnector(final Context ctx, String url, String methodType, final ArrayList<ArrayList<String>> postData,
                        final RequestCompleteListener<String> listener) {
    //postData has new data whenever class called
    if (methodType.equals("POST")) {
        method = Request.Method.POST;
    } else if (methodType.equals("GET")) {
        method = Request.Method.GET;
    }

    VolleySingleton volleySingleton = VolleySingleton.getInstance();
    requestQueue = volleySingleton.getRequestQueue();

    StringRequest stringRequest = new StringRequest(method, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    listener.onRequestExecuted("response", response);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("CCC", "Error " + error.toString());

                }
            })
    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            for (int i = 0; i < postData.size(); i++) {
                params.put(postData.get(i).get(0), postData.get(i).get(1));
                //postData sends old data here
                //so a hashmap is consists of old values
            }
            return params;
        }

        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            try {
                Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                if (cacheEntry == null) {
                    cacheEntry = new Cache.Entry();
                }
                final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
                final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
                long now = System.currentTimeMillis();
                final long softExpire = now + cacheHitButRefreshed;
                final long ttl = now + cacheExpired;
                cacheEntry.data = response.data;
                cacheEntry.softTtl = softExpire;
                cacheEntry.ttl = ttl;
                String headerValue;
                headerValue = response.headers.get("Date");
                if (headerValue != null) {
                    cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                headerValue = response.headers.get("Last-Modified");
                if (headerValue != null) {
                    cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                cacheEntry.responseHeaders = response.headers;
                final String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                return Response.success(jsonString, cacheEntry);
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            }
        }

        @Override
        protected void deliverResponse(String response) {
            super.deliverResponse(response);
        }

        @Override
        public void deliverError(VolleyError error) {
            super.deliverError(error);
        }

        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }
    };
    requestQueue.add(stringRequest);
}

2 个答案:

答案 0 :(得分:0)

在Volley的默认网络实现BasicNetwork中,您在performRequest(96)上有以下内容:

  

addCacheHeaders(headers,request.getCacheEntry());

这就是为什么你有这种行为的原因。所以很明显,如果你想要一个缓存条目,同时不发送一个,那么你需要自己实现/复制'CustomCacheNetwork',并为你的POST请求替换这一行。

然后你需要像这样创建你的队列:

    Network network = new CustomCacheNetwork(stack);
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);

然而,这种行为很奇怪,因为如果你有有效的缓存,你根本不会去网络调度员。

答案 1 :(得分:0)

这不是问题的解决方案,而是解决方法:

currentURL = url;
if (methodType.equals("POST")) {
   currentURL = currentURL + "?timestamp=" + String.valueOf(System.currentTimeMillis());
}

这里有一个虚拟参数,即时间戳正在发送到网站。该网站不使用此参数,因此,它不会改变任何内容。每次执行发布请求时,它只提供一个唯一的url来截击。在高速缓存存储期间,即在我的情况下为24小时,删除具有时间戳的URL的高速缓存数据,因此,高速缓存不会累积。

注意:对于发送或接收大量数据的url,建议不要使用此解决方法,并且当缓存可能已满时,会对URL进行大量的发布请求。