Prevent Volley from sending cached parameters on P

2019-09-09 17:25发布

I want volley to cache the response obtained from the server. Hence, I have implemented the caching code (ParseNetworkResponse). But volley is sending cached parameters when a POST request is made. How to prevent volley from doing this? Preferably how should the caching code below be modified to stop caching POST parameters? I want only the response from the server to be cached.

        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条回答
Bombasti
2楼-- · 2019-09-09 17:41

This is not a solution to the problem but a workaround:

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

Here a dummy parameter which is timestamp is being sent to the website. The website does not use this parameter and hence, it changes nothing. It just provides a unique url to volley every time a post request is executed. After the period of cache storage, i.e. 24hrs in my case, the cached data for the url with timestamp is deleted hence, cache doesn't buildup.

Note: this workaround is not recommended for url where large amount of data is sent or received and large volume of post request to the url are made as the cache may get full.

查看更多
3楼-- · 2019-09-09 17:49

in Volley's default Network implementation BasicNetwork you have the folloin line on performRequest(96):

addCacheHeaders(headers, request.getCacheEntry());

this is the cause why you have this behavior. So obviously if you want to have a cache entry and at the same time do not send one then you need to make your own implementation/copy 'CustomCacheNetwork' and replace this line for your POST requests.

then you need to create your queue like this:

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

This behavior however is strange because if you have valid cache you will not go to the network dispatcher at all.

查看更多
登录 后发表回答