当前位置: 首页 > 知识库问答 >
问题:

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

华浩壤
2023-03-14

我想让volley缓存从服务器获得的响应。因此,我实现了缓存代码(ParseNetworkResponse)。但volley会在发出POST请求时发送缓存的参数。如何防止凌空抽射这样做?最好应该如何修改下面的缓存代码来停止缓存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);
}

共有1个答案

史淳
2023-03-14

在Volley的默认网络实现BasicNetwork中,performRequest(96):

addCacheHeaders(headers,Request.GetCacheEntry());

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

那么您需要像这样创建您的队列:

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

然而,这种行为很奇怪,因为如果您有有效的缓存,您根本不会转到网络调度程序

 类似资料:
  • 在我的web应用程序上,我正在向url发送POST请求。它正常工作。 问题是,这个web应用程序也应该脱机工作。当由于连接问题而无法完成请求时,我将显示一个通知,当问题解决后,用户可以再次同步。 当我为了调试而断开internet连接时,我发现每次请求都返回200状态码。 浏览器不应该缓存POST请求,我错了吗? 在搜索堆栈溢出后,我尝试了这里编写的解决方案。 我试图从服务器(PHP/Ubuntu

  • 在我的Android应用程序中,我使用Volley在自定义列表视图中加载图像。 当我多次刷新(删除所有项目并加载tiems)listview时,我的应用程序就会被这条消息杀死 我该怎么修好它?

  • 我正在使用Volley从我的android应用程序向运行在http://192.168.1.4:3000/Battery_Signal_Report中的本地服务器发送一个带有参数的http post请求。我很确定服务器运行正常(我用Postman成功地检查了它)。 此外,我使用ip 10.0.2.2成功地通过Android Studio的模拟器发送了请求 为了使它正常工作,我使用了各种请求实现,包

  • 我想使用表单urlencoded参数制作POST JSONObjectRequest。我该怎么做?我尝试了以下代码,但无济于事。 我在api调用中收到了一个400错误的请求!我如何修复它?

  • 我有从我的网页生成的AJAX POST请求,可能有多个POST请求具有相同的POST数据。但是响应可能会有所不同,我希望确保我没有得到这些请求的缓存响应。我需要每个请求点击网页。 我假设对POST请求的响应不会被缓存,这对吗?

  • 我目前使用service/$resource进行ajax调用(在本例中是GET),IE缓存调用,以便无法从服务器检索新的数据。我使用了一种通过谷歌搜索找到的技术来创建一个随机数并将其附加到请求中,这样IE就不会为数据进行缓存。 还有比在每个请求中添加cacheKill更好的方法吗?