我有一个服务器请求,它返回多个cookie,如:
这就是我将这些cookie存储到cookieManager的方式:
HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();
msCookieManager.put(COOKIES_URI, connection.getHeaderFields());
这就是我将这些cookie添加到下一个连接的方式:
connection.setRequestProperty("Cookie",
msCookieManager.getCookieStore().get(COOKIES_URI).toString());
从cookieManager获取cookie是否正确? 我很确定有一个更好的......
答案 0 :(得分:97)
好的,正确的做法就是这样:
从响应标头中获取Cookie并将其加载到cookieManager中:
static final String COOKIES_HEADER = "Set-Cookie";
HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();
Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
msCookieManager.getCookieStore().add(null,HttpCookie.parse(cookie).get(0));
}
}
从CookieManager获取Cookie并将其加载到连接中:
if (msCookieManager.getCookieStore().getCookies().size() > 0) {
// While joining the Cookies, use ',' or ';' as needed. Most of the servers are using ';'
connection.setRequestProperty("Cookie",
TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
}
答案 1 :(得分:42)
我一直在寻找/尝试几天来解决我的问题: 即使在成功登录后也无法访问受保护的Web资源
我在iOS上创建了相同的应用程序并且没有相同的问题,因为NSUrlConnection在幕后为我们做了cookie维护。在Android上,我尝试手动添加cookie
connection.setRequestProperty("Cookie", "PHPSESSID=str_from_server")
没有任何运气。
最后我读了this
并在我的应用开头的某处添加了以下两行:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
现在一切正常。
答案 2 :(得分:3)
@David的答案是最好的。最简单的方法是维护本地CookieManager并手动写入和读取与此cookie管理器关联的cookie存储区。
此代码将响应中的Cookie加载到cookie管理器中:
/**
* Gets Cookies from the response header and loads them into cookie manager
*
* @param conn instance of {@link HttpURLConnection} object
* @param cookieManager the cookie manager({@link CookieManager} instance) in which the cookies are to be loaded<p>In case a null object is passed, the function will not perform any action and return back to the caller. </p>
*/
public static void loadResponseCookies(@Nullable HttpURLConnection conn,@Nullable CookieManager cookieManager) {
//do nothing in case a null cokkie manager object is passed
if (cookieManager == null || conn == null){
return;
}
List<String> cookiesHeader = conn.getHeaderFields().get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookieHeader : cookiesHeader) {
List<HttpCookie> cookies;
try {
cookies = HttpCookie.parse(cookieHeader);
} catch (NullPointerException e) {
log.warn(MessageFormat.format("{0} -- Null header for the cookie : {1}",conn.getURL().toString(), cookieHeader.toString()));
//ignore the Null cookie header and proceed to the next cookie header
continue;
}
if (cookies != null) {
Debug("{0} -- Reading Cookies from the response :", conn.getURL().toString());
for (HttpCookie cookie : cookies) {
Debug(cookie.toString());
}
if (cookies.size() > 0) {
cookieManager.getCookieStore().add(null, HttpCookie.parse(cookieHeader).get(0));
}
}
}
}
}
此代码使用与cookie管理器关联的cookie填充HttpUrlConnection对象:
public void populateCookieHeaders(HttpURLConnection conn) {
if (this.cookieManager != null) {
//getting cookies(if any) and manually adding them to the request header
List<HttpCookie> cookies = this.cookieManager.getCookieStore().getCookies();
if (cookies != null) {
if (cookies.size() > 0) {
Debug("{0} -- Adding Cookie Headers : ", url.toString());
for (HttpCookie cookie : cookies) {
Debug(cookie.toString(), null);
}
//adding the cookie header
conn.setRequestProperty(COOKIE_REQUEST_HEADER, StringUtils.join(cookies, ";"));
}
}
}
}
这是处理cookie的最安全的方法。
我尝试使用threadlocal cookiestore和CookieManager的扩展。在我的案例中,这些方法都不起作用。
答案 3 :(得分:1)
其他答案也适合于它们的上下文,但是没有人说明显的话:CookieHandler在大多数情况下会自动处理您的cookie。要仅维护从一个请求到下一个请求的cookie(例如维护服务器会话),那么此行代码就足够了:
exec('php slowasf.php arg1 arg2 >/dev/null 2>/dev/null &');
确保在您第一次向UrlConnection发出请求之前运行它一次。
现在我自己进行零cookie管理,并且从请求到请求的所有服务器会话数据都得到了完美维护。
我疯了吗?互联网为什么对此保持沉默?我什至在文档中找不到它。
答案 4 :(得分:0)
使用java.net.HttpURLConnection
和groovy,只需在with
封闭内添加URLConnection#addRequestProperty(String key, String value)
。
import java.net.HttpURLConnection
HttpURLConnection createRequest(String chatRequestBody) {
HttpURLConnection httpChatRequest = new URL("${endpoint}").openConnection() as HttpURLConnection
httpChatRequest.with {
doOutput = true
requestMethod = 'POST'
//headers
addRequestProperty("Content-Type", "application/json")
addRequestProperty("Client-Platform", "android")
//cookies
addRequestProperty("Cookie", "cookie_key1=cookie_value1,cookie_key2=cookie_value2")
getOutputStream().write(chatRequestBody.getBytes("UTF-8"))
}
httpChatRequest
}