今天下午用 HtmlUnit做新浪的登陆,由于新浪的多域名原因,出现了下面警告
Cookie rejected: "[version: 0][name: U_TRS1][value: 000000e4.603e4743.527caa18.4f2f5b0d][domain: .sina.com.cn][path: /][expiry: Mon Nov 06 17:08:40 CST 2023]". Illegal domain attribute "sina.com.cn". Domain of origin: "account.weibo.com"
大概意思就是Cookie被拒绝,域名的问题。
百度了几篇,答案代码通通没效果,然后去Google了一下,发现挺多老外也遇到了这个问题。
其中 Stack Overflow 里面有一个最佳答案,说的是重写 CookieManager 里面的 getCookies(final URL url) 方法,然后webClient.setCookieManager(myManager);进去。
我照着做了下,发现没用。
后来下载了源码,自己进行DEBUG,发现getCookies(final URL url)方法根本没有执行,反而执行了getCookies(); 方法
/** * Returns the currently configured cookies, in an unmodifiable set. * @return the currently configured cookies, in an unmodifiable set */ public synchronized Set<Cookie> getCookies() { final Set<Cookie> copy = new HashSet<Cookie>(cookies_); return Collections.unmodifiableSet(copy); }
于是我一层一层找下去,最后发现org.apache.http.impl.cookie.BasicDomainHandler.java 里,有一个public void validate(final Cookie cookie, final CookieOrigin origin)被调用,然后这个方法验证失败后抛出了异常,打印log :Cookie rejected。。。
for (Cookie cookie : cookies) { try { cookieSpec.validate(cookie, cookieOrigin); cookieStore.addCookie(cookie); if (this.log.isDebugEnabled()) { this.log.debug("Cookie accepted: \"" + cookie + "\". "); } } catch (MalformedCookieException ex) { if (this.log.isWarnEnabled()) { this.log.warn("Cookie rejected: \"" + cookie + "\". " + ex.getMessage()); } } }
我重写了这个方法,搞定。不过要注意的是,重写这个方法不能完全注释掉它的验证,需要针对性的重写,否则可能会引发其他验证问题。
最后,我发现我犯了一个错误,虽然Cookie最后是弄进去了,但是这次错误的主要原因是 我误以为 weibo.cn 跟 weibo.com 的Cookie可以共享的。。但是实际上它不像sina.com ..weibo.com..等其他域名一样,一个Cookie可以通吃。
最后介绍个学习网站:http://gz.itcast.cn/