如何parsing一个cookiestring

我想要一个Cookiestring(因为它可能会返回一个Set-Cookie头),并能够轻松修改它的一部分,特别是到期date。

我看到有几个不同的Cookie类,例如BasicClientCookie,但我没有看到任何简单的方法来parsingstring到这些对象之一。

我在api 9级看到他们添加了HttpCookie ,它有一个parsing方法,但是我需要一些东西在以前的版本中工作。

有任何想法吗?

谢谢

Solutions Collecting From Web of "如何parsing一个cookiestring"

我相信你将不得不手动parsing它。 尝试这个:

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; } 

我没有真正编译或运行这个代码,但它应该是一个强有力的开始。 你可能不得不把dateparsing一下:我不确定cookie中使用的date格式实际上是否与DateFormat.FULL相同。 (查看这个相关的问题,哪些地址处理cookie中的date格式。)另外,请注意,有一些Cookie属性没有被BasicClientCookie处理,比如versionhttponly

最后,这段代码假定cookie的名称和值显示为第一个属性:我不确定这是否一定是正确的,但是这就是我见过的每个cookie的sorting顺序。

如何java.net.HttpCookie

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

你可以使用Apache HttpClient的设施。
以下是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; } 

正则expression式如下所示:

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

你可以像这样parsing一个cookie:

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

在几行代码中。

有趣的是,但是java.net.HttpCookie类不能parsing带有这个确切的java.net.HttpCookie类已经转换为string的域和/或path部分的cookiestring。

例如:

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

由于这个类既没有实现Serializable也没有Parcelable,所以很容易将cookies存储为string。 所以你写这样的东西:

 saveMyCookieAsString(newCookie.toString()); 

此声明将以下列格式保存Cookie:

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

然后你想恢复这个cookie,所以你得到的string:

 String cookieAsString = restoreMyCookieString(); 

并试图parsing它:

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

现在myCookieAsStringNow.toString(); 产生

 cookieName=cookieValue 

域和path部分刚刚消失 。 原因:parsing方法对像“域”和“path”这样的词是区分大小写的。
可能的解决方法:提供另一个toString()方法,如:

 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(); } 

我觉得这很有趣(特别是java.net.HttpCookie这样的类,目的是被很多人使用),我希望这会对某个人有用。

Yanchenko使用Apache Http客户端的方法的优点在于,根据来源validation与规范一致的cookie。 正则expression式的方法不会这样做,但也许你不需要。

 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; } } 

我使用yanchenkos正则expression式附加了一个小例子。 它需要稍微调整一下。 没有'?' 数量修改后的“;” 任何cookie的尾部属性都不会匹配。 之后,如果您关心其他属性,则可以使用Doug的代码(正确封装)来parsing其他匹配组。

编辑:另外,请注意“*”限定符的cookie本身的价值。 值是可选的,你可以得到像“de =”这样的cookies,即没有任何价值。 再看看正则expression式,我不认为它会处理没有'='的安全和丢弃cookie属性。

 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();