Cómo analizar una cadena de cookies

Me gustaría tomar una cadena de cookies (como podría ser devuelto en un encabezado Set-Cookie) y ser capaz de modificar fácilmente partes de ella, específicamente la fecha de caducidad.

Veo que hay varias diversas clases de la galleta, tales como BasicClientCookie, disponible pero no veo ninguna manera fácil de analizar la secuencia en uno de esos objetos.

Veo en api nivel 9 que agregaron HttpCookie que tiene un método de análisis, pero necesito algo para trabajar en versiones anteriores.

¿Algunas ideas?

Gracias

7 Solutions collect form web for “Cómo analizar una cadena de cookies”

Creo que tendrás que analizarlo manualmente. Prueba esto:

BasicClientCookie parseRawCookie(String rawCookie) throws Exception { String[] rawCookieParams = rawCookie.split(";"); String[] rawCookieNameAndValue = rawCookieParams[0].split("="); if (rawCookieNameAndValue.length != 2) { throw new Exception("Invalid cookie: missing name and value."); } String cookieName = rawCookieNameAndValue[0].trim(); String cookieValue = rawCookieNameAndValue[1].trim(); BasicClientCookie cookie = new BasicClientCookie(cookieName, cookieValue); for (int i = 1; i < rawCookieParams.length; i++) { String rawCookieParamNameAndValue[] = rawCookieParams[i].trim().split("="); String paramName = rawCookieParamNameAndValue[0].trim(); if (paramName.equalsIgnoreCase("secure")) { cookie.setSecure(true); } else { if (rawCookieParamNameAndValue.length != 2) { throw new Exception("Invalid cookie: attribute not a flag or missing value."); } String paramValue = rawCookieParamNameAndValue[1].trim(); if (paramName.equalsIgnoreCase("expires")) { Date expiryDate = DateFormat.getDateTimeInstance(DateFormat.FULL) .parse(paramValue); cookie.setExpiryDate(expiryDate); } else if (paramName.equalsIgnoreCase("max-age")) { long maxAge = Long.parseLong(paramValue); Date expiryDate = new Date(System.getCurrentTimeMillis() + maxAge); cookie.setExpiryDate(expiryDate); } else if (paramName.equalsIgnoreCase("domain")) { cookie.setDomain(paramValue); } else if (paramName.equalsIgnoreCase("path")) { cookie.setPath(paramValue); } else if (paramName.equalsIgnoreCase("comment")) { cookie.setPath(paramValue); } else { throw new Exception("Invalid cookie: invalid attribute name."); } } } return cookie; } 

En realidad no he compilado o ejecutar este código, pero debe ser un comienzo fuerte. Usted probablemente tendrá que meterse con la fecha de analizar un poco: No estoy seguro de que el formato de fecha utilizado en las cookies es en realidad el mismo que DateFormat.FULL . (Consulte esta pregunta relacionada, que trata el manejo del formato de fecha en las cookies.) Además, tenga en cuenta que hay algunos atributos de cookie que no son manejados por BasicClientCookie , como version y httponly .

Por último, este código supone que el nombre y el valor de la cookie aparecen como el primer atributo: No estoy seguro si eso es necesariamente cierto, pero así es como cada cookie que he visto está ordenada.

¿Qué tal java.net.HttpCookie :

 List<HttpCookie> cookies = HttpCookie.parse(header); 

Puede utilizar las instalaciones de Apache HttpClient para eso.
Aquí hay un extracto de CookieJar :

 CookieSpec cookieSpec = new BrowserCompatSpec(); List<Cookie> parseCookies(URI uri, List<String> cookieHeaders) { ArrayList<Cookie> cookies = new ArrayList<Cookie>(); int port = (uri.getPort() < 0) ? 80 : uri.getPort(); boolean secure = "https".equals(uri.getScheme()); CookieOrigin origin = new CookieOrigin(uri.getHost(), port, uri.getPath(), secure); for (String cookieHeader : cookieHeaders) { BasicHeader header = new BasicHeader(SM.SET_COOKIE, cookieHeader); try { cookies.addAll(cookieSpec.parse(header, origin)); } catch (MalformedCookieException e) { Ld(e); } } return cookies; } 

Con una expresión regular como:

 ([^=]+)=([^\;]+);\s? 

Puede analizar una cookie como esta:

 .COOKIEAUTH=5DEF0BF530F749AD46F652BDF31C372526A42FEB9D40162167CB39C4D43FC8AF1C4B6DF0C24ECB1945DFF7952C70FDA1E4AF12C1803F9D089E78348C4B41802279897807F85905D6B6D2D42896BA2A267E9F564814631B4B31EE41A483C886B14B5A1E76FD264FB230E87877CB9A4A2A7BDB0B0101BC2C1AF3A029CC54EE4FBC; expires=Sat, 30-Jul-2011 01:22:34 GMT; path=/; HttpOnly 

En unas pocas líneas de código.

Bastante divertido, pero la clase de java.net.HttpCookie no puede analizar las secuencias de la galleta con las piezas del dominio y / o de la trayectoria que esta clase exacta de java.net.HttpCookie ha convertido a las secuencias.

Por ejemplo:

 HttpCookie newCookie = new HttpCookie("cookieName", "cookieValue"); newCookie.setDomain("cookieDomain.com"); newCookie.setPath("/"); 

Como esta clase implementa ni Serializable ni Parcelable, es tentador almacenar cookies como cadenas. Así que escribe algo como:

 saveMyCookieAsString(newCookie.toString()); 

Esta declaración guardará la cookie en el siguiente formato:

 cookieName="cookieValue";$Path="/";$Domain="cookiedomain.com" 

Y luego quieres restaurar esta cookie, así que obtienes la cadena:

 String cookieAsString = restoreMyCookieString(); 

Y tratar de analizarlo:

 List<HttpCookie> cookiesList = HttpCookie.parse(cookieAsString); StringBuilder myCookieAsStringNow = new StringBuilder(); for(HttpCookie httpCookie: cookiesList) { myCookieAsStringNow.append(httpCookie.toString()); } 

Ahora myCookieAsStringNow.toString(); Produce

 cookieName=cookieValue 

Las partes del dominio y de la trayectoria apenas se han ido . La razón: método de análisis es sensible a mayúsculas y minúsculas a palabras como "dominio" y "ruta de acceso".
Posible solución: proporcione otro método toString () como:

 public static String httpCookieToString(HttpCookie httpCookie) { StringBuilder result = new StringBuilder() .append(httpCookie.getName()) .append("=") .append("\"") .append(httpCookie.getValue()) .append("\""); if(!TextUtils.isEmpty(httpCookie.getDomain())) { result.append("; domain=") .append(httpCookie.getDomain()); } if(!TextUtils.isEmpty(httpCookie.getPath())){ result.append("; path=") .append(httpCookie.getPath()); } return result.toString(); } 

Me parece gracioso (especialmente, para las clases como java.net.HttpCookie que están destinados a ser utilizado por un montón y mucha gente) y espero que sea útil para alguien.

La ventaja del enfoque de Yanchenko con el cliente Apache Http es que valida las cookies consistentes con las especificaciones basadas en el origen. El enfoque de expresión regular no lo hará, pero tal vez no es necesario.

 public class CookieUtil { public List<Cookie> parseCookieString(String cookies) { List<Cookie> cookieList = new ArrayList<Cookie>(); Pattern cookiePattern = Pattern.compile("([^=]+)=([^\\;]*);?\\s?"); Matcher matcher = cookiePattern.matcher(cookies); while (matcher.find()) { int groupCount = matcher.groupCount(); System.out.println("matched: " + matcher.group(0)); for (int groupIndex = 0; groupIndex <= groupCount; ++groupIndex) { System.out.println("group[" + groupIndex + "]=" + matcher.group(groupIndex)); } String cookieKey = matcher.group(1); String cookieValue = matcher.group(2); Cookie cookie = new BasicClientCookie(cookieKey, cookieValue); cookieList.add(cookie); } return cookieList; } } 

He adjuntado un pequeño ejemplo usando regex yanchenkos. Necesita ser ajustado un poco. Sin el '?' Modificador de la cantidad en el arrastre ';' El atributo de arrastre para cualquier cookie no coincidirá. Después de eso, si te interesan los otros atributos, puedes usar el código de Doug, adecuadamente encapsulado, para analizar los otros grupos de coincidencias.

Editar: También, tenga en cuenta el calificador '*' en el valor de la propia cookie. Los valores son opcionales y puedes obtener cookies como "de =", es decir, sin valor alguno. Mirando el regex otra vez, no pienso que manejará los atributos seguros y desechados de la galleta que no tienen '='.

 CookieManager cookieManager = new CookieManager(); CookieHandler.setDefault(cookieManager); HttpCookie cookie = new HttpCookie("lang", "en"); cookie.setDomain("Your URL"); cookie.setPath("/"); cookie.setVersion(0); cookieManager.getCookieStore().add(new URI("https://Your URL/"), cookie); List<HttpCookie> Cookies = cookieManager.getCookieStore().get(new URI("https://Your URL/")); String s = Cookies.get(0).getValue(); 
  • Anidados if / else, switches o algo más eficiente para el combate RPG?
  • Localización de recursos en la aplicación android
  • Cifrado utilizando AES-128 en Android e IPhone (Resultado diferente)
  • Descripción de la arquitectura de los contactos de Android
  • ¿Cómo puedo manejar múltiples clientes conectados a un servidor mediante sockets?
  • Cómo puedo extraer datos rtsp en MediaCodec
  • IText crear un documento con tamaños de página desiguales
  • Debe llamar a removeView () en el padre del niño primero con AlertView
  • ListView onScroll añadir más elementos
  • ¿Cómo puedo agregar datos que he introducido en un cuadro de EditText en una matriz para enumerar en otra actividad?
  • Quitar ActionBar en API debajo de 11
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.