版本是httpclient-4.5.6
在网站上获取cookie想拿出来在代码里面放到CookieStore里面模拟请求但是失败了,可我直接把cookie放到head里面确是正常的。
BasicClientCookie cookie = new BasicClientCookie(jo.getString("name"),jo.getString("value"));
cookie.setSecure(false);
cookie.setDomain(domain);
cookie.setPath(path);
cookie.setVersion(version);
cookieStore.addCookie(cookie);
我用抓包工具抓包发现放在cookiesstore确是没有携带cookie,放在head里面是有的。
后面查源码发现在请求的时候回用httppress把cookiestore里面的内容解析成cookie放到head里面,但是中间验证了很多东西。包括isSecure,Domain,Expiry等等,都有对应的handler进行match。最后在BasicDomainHandler的match发现会验证cookie里面的attribs里面是否包含domain。
if (((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR))
但是并没有在BasicClientCookie发现哪里有自动设置attribs内容的,所以这个是手动添加的。
然后尝试发请求的时候看一下BasicClientCookie是怎么生成的。发现在CookieSpecBase里面会解析head里面的cookie字段,存储成BasicClientCookie。
protected List<Cookie> parse(final HeaderElement[] elems, final CookieOrigin origin)
throws MalformedCookieException {
final List<Cookie> cookies = new ArrayList<Cookie>(elems.length);
for (final HeaderElement headerelement : elems) {
final String name = headerelement.getName();
final String value = headerelement.getValue();
if (name == null || name.isEmpty()) {
continue;
}
final BasicClientCookie cookie = new BasicClientCookie(name, value);
cookie.setPath(getDefaultPath(origin));
cookie.setDomain(getDefaultDomain(origin));
// cycle through the parameters
final NameValuePair[] attribs = headerelement.getParameters();
for (int j = attribs.length - 1; j >= 0; j--) {
final NameValuePair attrib = attribs[j];
final String s = attrib.getName().toLowerCase(Locale.ROOT);
cookie.setAttribute(s, attrib.getValue());
final CookieAttributeHandler handler = findAttribHandler(s);
if (handler != null) {
handler.parse(cookie, attrib.getValue());
}
}
cookies.add(cookie);
}
return cookies;
}
这里面会进行setAttribute操作,同时把key转成小写。
疑问结束。
然后我这样设置:
BasicClientCookie cookie = new BasicClientCookie(jo.getString("name"),jo.getString("value"));
cookie.setSecure(false);
cookie.setDomain(domain);
cookie.setPath(path);
cookie.setVersion(version);
cookieStore2.addCookie(cookie);
if(domain != null) cookie.setAttribute("domain", domain);
if(path != null) cookie.setAttribute("path", path);
if(expiry != null) cookie.setAttribute("expiry", expiry);
就能正常了。
写在最后:
其实我初衷是想把cookie存储到本地,以后每次都携带cookie的,但是使用ObjectOutputStream序列化对象保存,发现在linux下不能正确读取,估计是jdk版本不同导致。所以我想用json存储,然后每次进行解析,但是出了上面的幺蛾子。