谢谢大家。
我已经赞成了所有的答案,但是没有一个提供完整的解决方案。
由于在谷歌搜索这个问题会导致跳转到这个页面,所以我将发布完整的解决方案并接受自己的答案:
操作方法:
1 将CookieHandler
扩展为SessionCookieManager
这基于如何在Java中使用HttpURLConnection和CookieManager为每个连接使用不同的cookie,nivs描述得很正确,但没有提供完整的解决方案。因此,大部分或全部功劳归于他,我只是完成了完整的操作方法。SessionCookieManager基于Java
的源代码http://docs.oracle.com/javase/7/docs/api/java/net/CookieManager.html
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URI;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class SessionCookieManager extends CookieHandler
{
private CookiePolicy policyCallback;
public SessionCookieManager() {
this(null, null);
}
private final static SessionCookieManager ms_instance = new SessionCookieManager();
public static SessionCookieManager getInstance()
{
return ms_instance;
}
private final static ThreadLocal<CookieStore> ms_cookieJars = new ThreadLocal<CookieStore>() {
@Override
protected synchronized CookieStore initialValue() { return new InMemoryCookieStore(); }
};
public void clear()
{
getCookieStore().removeAll();
}
public SessionCookieManager(CookieStore store,
CookiePolicy cookiePolicy)
{
policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ALL
: cookiePolicy;
}
public void setCookiePolicy(CookiePolicy cookiePolicy) {
if (cookiePolicy != null) policyCallback = cookiePolicy;
}
public CookieStore getCookieStore() {
return ms_cookieJars.get();
}
public Map<String, List<String>>
get(URI uri, Map<String, List<String>> requestHeaders)
throws IOException
{
if (uri == null || requestHeaders == null) {
throw new IllegalArgumentException("Argument is null");
}
Map<String, List<String>> cookieMap =
new java.util.HashMap<String, List<String>>();
if (getCookieStore() == null)
return Collections.unmodifiableMap(cookieMap);
List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
for (HttpCookie cookie : getCookieStore().get(uri)) {
if (pathMatches(uri.getPath(), cookie.getPath())) {
cookies.add(cookie);
}
}
List<String> cookieHeader = sortByPath(cookies);
cookieMap.put("Cookie", cookieHeader);
return Collections.unmodifiableMap(cookieMap);
}
public void
put(URI uri, Map<String, List<String>> responseHeaders)
throws IOException
{
if (uri == null || responseHeaders == null) {
throw new IllegalArgumentException("Argument is null");
}
if (getCookieStore() == null)
return;
for (String headerKey : responseHeaders.keySet()) {
if (headerKey == null
|| !(headerKey.equalsIgnoreCase("Set-Cookie2")
|| headerKey.equalsIgnoreCase("Set-Cookie")
)
)
{
continue;
}
for (String headerValue : responseHeaders.get(headerKey)) {
try {
List<HttpCookie> cookies = HttpCookie.parse(headerValue);
for (HttpCookie cookie : cookies) {
if (shouldAcceptInternal(uri, cookie)) {
getCookieStore().add(uri, cookie);
}
}
} catch (IllegalArgumentException e) {
}
}
}
}
private boolean shouldAcceptInternal(URI uri, HttpCookie cookie) {
try {
return policyCallback.shouldAccept(uri, cookie);
} catch (Exception ignored) {
return false;
}
}
private boolean pathMatches(String path, String pathToMatchWith) {
if (path == pathToMatchWith)
return true;
if (path == null || pathToMatchWith == null)
return false;
if (path.startsWith(pathToMatchWith))
return true;
return false;
}
private List<String> sortByPath(List<HttpCookie> cookies) {
Collections.sort(cookies, new CookiePathComparator());
List<String> cookieHeader = new java.util.ArrayList<String>();
for (HttpCookie cookie : cookies) {
if (cookies.indexOf(cookie) == 0 && cookie.getVersion() > 0) {
cookieHeader.add("$Version=\"1\"");
}
cookieHeader.add(cookie.toString());
}
return cookieHeader;
}
static class CookiePathComparator implements Comparator<HttpCookie> {
public int compare(HttpCookie c1, HttpCookie c2) {
if (c1 == c2) return 0;
if (c1 == null) return -1;
if (c2 == null) return 1;
if (!c1.getName().equals(c2.getName())) return 0;
if (c1.getPath().startsWith(c2.getPath()))
return -1;
else if (c2.getPath().startsWith(c1.getPath()))
return 1;
else
return 0;
}
}
}
注意,在我的情况下,我将
CookiePolicy
的默认值更改为
ACCEPT_ALL
全局范围内,在运行任何线程之前调用:
CookieHandler.setDefault(SessionCookieManager.getInstance())
3 当您的线程完成时,请在其中调用:
SessionCookieManager.getInstance().clear()
再次声明:这不是我的想法,只是将它们组合在一起。 非常感谢Java
和https://stackoverflow.com/users/1442259/nivs的贡献。