现在的位置: 首页 > 移动开发 > 正文

Android Volley支持多个cookie

2018年07月12日 移动开发 ⁄ 共 3293字 ⁄ 字号 评论关闭

      原创文章,转载请注明出处:http://blog.csdn.net/wj2030/article/details/43731703

       最近在做一个项目,考虑到volley使用比较方便,就将其选择为网络工具。可是在使用途中发现,由于我们的项目在登录验证的时候,返回了多个cookie.也就是返回的头信息中Set-Cookie有多个值,但是volley在onResponse中只能得到一个cookie.刚开始非常郁闷,以至于我又用HttpClient编写了一个测试程序。发现,的确是volley的问题。找到问题就好办了,volley是开源的想怎么修改,就怎么修改。

         关于volley的详解,不了解的可以看看郭神的博客。这里附上郭神的文章地址:http://blog.csdn.net/guolin_blog/article/details/17482095   

         可以知道,在网络通信过程中volley会根据版本号选择使用httpclientStack或则hurlStack。通过查看两者的源代码如下:

HttpClientStack-->

public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
        addHeaders(httpRequest, additionalHeaders);
        addHeaders(httpRequest, request.getHeaders());
        onPrepareRequest(httpRequest);
        HttpParams httpParams = httpRequest.getParams();
        int timeoutMs = request.getTimeoutMs();
        // TODO: Reevaluate this connection timeout based on more wide-scale
        // data collection and possibly different for wifi vs. 3G.
        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
        HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
        return mClient.execute(httpRequest);
    }

很明显没啥异常。但是HurlStack-->中如下:

public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError {
String url = request.getUrl();
HashMap<String, String> map = new HashMap<String, String>();
map.putAll(request.getHeaders());
map.putAll(additionalHeaders);
if (mUrlRewriter != null) {
String rewritten = mUrlRewriter.rewriteUrl(url);
if (rewritten == null) {
throw new IOException("URL blocked by rewriter: " + url);
}
url = rewritten;
}
URL parsedUrl = new URL(url);
HttpURLConnection connection = openConnection(parsedUrl, request);
for (String headerName : map.keySet()) {
connection.addRequestProperty(headerName, map.get(headerName));
}
setConnectionParametersForRequest(connection, request);
// Initialize HttpResponse with data from the HttpURLConnection.
ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
int responseCode = connection.getResponseCode();
if (responseCode == -1) {
// -1 is returned by getResponseCode() if the response code could not be retrieved.
// Signal to the caller that something was wrong with the connection.
throw new IOException("Could not retrieve response code from HttpUrlConnection.");
}
StatusLine responseStatus = new BasicStatusLine(protocolVersion,
connection.getResponseCode(), connection.getResponseMessage());
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
response.setEntity(entityFromConnection(connection));
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
if (header.getKey() != null) {
Header h = new BasicHeader(header.getKey(), header.getValue().get(0));                    // 这里发现一个问题
response.addHeader(h);
}
}
return response;
}

如上注释,我们可以看到,在hurlStack中,添加到response中的header只是每一中头信息的第一项,也就是导致我Set-Cookie最后只有第一个cookie后面的都没有了。既然发现里问题,那就修改,只需要修改一点,我的修改如下:

for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
            if (header.getKey() != null) {
                StringBuffer sb = new StringBuffer();
                for(int i=0;i<header.getValue().size();i++){
                    sb.append(header.getValue().get(i));
                    sb.append("\n");
                }
                Header h = new BasicHeader(header.getKey(),sb.toString());
                //Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
                response.addHeader(h);
            }
        }

这样返回的response中的头信息就全部在里,只是每一个cookie之间添加里一个回车而已。下面贴上我打包生存的.arr文件。方便各位使用。

http://download.csdn.net/detail/wj2030/8439845

抱歉!评论已关闭.