J'ai une demande de serveur qui renvoie plusieurs cookies, comme celui-ci:
Voici comment je stocke ces cookies dans le cookieManager:
HttpURLConnection connection = ... ;
static Java.net.CookieManager msCookieManager = new Java.net.CookieManager();
msCookieManager.put(COOKIES_URI, connection.getHeaderFields());
Voici comment j'ajoute ces cookies à la prochaine connexion:
connection.setRequestProperty("Cookie",
msCookieManager.getCookieStore().get(COOKIES_URI).toString());
Est-ce la bonne façon d'obtenir les cookies du cookieManager?, Je suis presque sûr qu'il y en a un meilleur ...
Ok, la bonne façon de le faire est juste comme ça:
Obtenir les cookies de l'en-tête de la réponse et les charger dans 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));
}
}
Obtenir les cookies de cookieManager et les charger dans la connexion:
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()));
}
Cela fait des jours que je cherche/tente de résoudre mon problème: Je ne peux pas accéder aux ressources Web protégées même après une connexion réussie.
J'ai créé la même application sur iOS et je n'ai pas eu le même problème, car NSUrlConnection a effectué la maintenance des cookies pour nous dans les coulisses. Sur Android, j'ai essayé d'ajouter manuellement un cookie
connection.setRequestProperty("Cookie", "PHPSESSID=str_from_server")
sans aucune chance.
Enfin j'ai lu ceci
et ajouté les 2 lignes suivantes quelque part au début de mon application:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
et tout fonctionne bien maintenant.
@ La réponse de David est la meilleure du lot. Il est plus facile de gérer un CookieManager local et d'écrire et de lire manuellement dans le magasin de cookies associé à ce gestionnaire de cookies.
Ce code charge les cookies d'une réponse dans le gestionnaire de cookies:
/**
* 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));
}
}
}
}
}
Ce code renseigne l'objet HttpUrlConnection avec les cookies associés au gestionnaire de cookies:
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, ";"));
}
}
}
}
C'est le moyen le plus sûr de gérer les cookies.
J'ai essayé d'utiliser un cookiestore threadlocal et une extension de CookieManager. Aucune de ces approches n'a fonctionné dans mon cas.
en utilisant Java.net.HttpURLConnection
et groovy, ajoutez simplement URLConnection#addRequestProperty(String key, String value)
inside with
fermeture.
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
}
La réponse acceptée peut fonctionner, mais j'ai trouvé une solution plus simple. La solution de Gold Thumb n'a pas fonctionné dans mon cas. Voir ma réponse connexion webView & httpUrlConnection