在使用HttpResponse中的HttpClient进行连接时,能够获得所有可能的“set-cookie”标头值(JESSIONID和XSCRF-TOKEN)。请查看下面的截图。
现在使用android studio和volley api进行连接,我只得到“set-cookie”标题的单个值(仅限JESSIONID)。参见下文:
我还检查了https://groups.google.com/forum/#!topic/volley-users/rNTlV-LORzY。 必须在volley api jar项目中进行更改。但不知道如何编辑凌空api。如果有任何其他解决方案,请提供指导。
请使用volley api帮助检索“set-cookie”的多个值。
答案 0 :(得分:3)
<强>问题:强>
不幸的是,问题出在了Volley内部。我遇到了这个问题,经过多次搜索,我发现在convertHeaders
类中有一个名为BasicNetwork
的方法可以处理这样的标题:
protected static Map<String, String> convertHeaders(Header[] headers) {
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < headers.length; i++) {
result.put(headers[i].getName(), headers[i].getValue());
}
return result;
}
您会看到结果为Map<String, String>
,但不能包含具有不同值的相同键。所以你总是只有最后一个cookie
cookie设置的标准告诉我们,我们应该将cookie与;
分开,例如,如果您想在请求cookie中包含2个键值,您应该将它们放在这样:
Cookies: k1=v1;k2=v2
<强>解决方案:强>
在您的情况下,您有两种选择。
1 - 更改服务器端的代码,以便响应仅包含 1 Set-Cookie
分隔的键值;
。 您的回复示例:
Set-Cookie: JESSIONID=qZtQ...;Path=/;HttpOnly;XSRF-TOKEN=6c65...
2 - 获取Volley源代码并更改该buggy方法并再次修复.jar!这个选项是我最喜欢的,因为你没有触及服务器的响应
我对此方法的实现是:
protected static Map<String, String> convertHeaders(Header[] headers) {
TreeMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER);
for(int i = 0; i < headers.length; ++i) {
String headerName = headers[i].getName();
if(!result.containsKey(headerName)) {
result.put(headers[i].getName(), headers[i].getValue());
} else {
String value = (String)result.get(headerName);
String mergedValue = value + ";" + headers[i].getValue();
result.remove(headerName);
result.put(headerName, mergedValue);
}
}
return result;
}
答案 1 :(得分:0)
有以下解决方法:
implementation "com.android.volley:volley:1.1.0"
“ NetworkResponse(和Cache.Entry)现在包含“ allHeaders”字段,该字段是服务器返回的所有标头的原始列表,因此可以按名称包含重复项。”
来源:https://github.com/google/volley/issues/21
示例:
private static final String COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_NAME = "NameOfOneOfTheCookies";
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
handleCookies(response);
String parsed;
try {
parsed = new String(response.data, "utf-8");
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed,
HttpHeaderParser.parseCacheHeaders(response));
}
private void handleCookies(NetworkResponse response) {
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY) && header.getValue().startsWith(COOKIE_NAME)) {
getCookies(response);
}
}
}
private void getCookies(NetworkResponse response) {
ArrayList<String> cookiesList = new ArrayList<>();
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY)) {
cookiesList.add(header.getValue());
}
}
// TODO Do something with the cookiesList
}