Home » Android » java – How to parse a cookie string

java – How to parse a cookie string

Posted by: admin April 23, 2020 Leave a comment


I would like to take a Cookie string (as it might be returned in a Set-Cookie header) and be able to easily modify parts of it, specifically the expiration date.

I see there are several different Cookie classes, such as BasicClientCookie, available but I don’t see any easy way to parse the string into one of those objects.

I see in api level 9 they added HttpCookie which has a parse method, but I need something to work in previous versions.

Any ideas?


How to&Answers:

I believe you’ll have to parse it out manually. Try this:

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")) {
        } 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)
            } else if (paramName.equalsIgnoreCase("max-age")) {
                long maxAge = Long.parseLong(paramValue);
                Date expiryDate = new Date(System.getCurrentTimeMillis() + maxAge);
            } else if (paramName.equalsIgnoreCase("domain")) {
            } else if (paramName.equalsIgnoreCase("path")) {
            } else if (paramName.equalsIgnoreCase("comment")) {
            } else {
                throw new Exception("Invalid cookie: invalid attribute name.");

    return cookie;

I haven’t actually compiled or run this code, but it should be a strong start. You’ll probably have to mess with the date parsing a bit: I’m not sure that the date format used in cookies is actually the same as DateFormat.FULL. (Check out this related question, which addresses handling the date format in cookies.) Also, note that there are some cookie attributes not handled by BasicClientCookie such as version and httponly.

Finally, this code assumes that the name and value of the cookie appear as the first attribute: I’m not sure if that’s necessarily true, but that’s how every cookie I’ve ever seen is ordered.


How about java.net.HttpCookie:

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


You can use Apache HttpClient‘s facilities for that.
Here’s an excerpt from 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) {
    return cookies;


Funny enough, but java.net.HttpCookie class cannot parse cookie strings with domain and/or path parts that this exact java.net.HttpCookie class has converted to strings.

For example:

HttpCookie newCookie = new HttpCookie("cookieName", "cookieValue");

As this class implements neither Serializable nor Parcelable, it’s tempting to store cookies as strings. So you write something like:


This statement will save the cookie in the following format:


And then you want to restore this cookie, so you get the string:

String cookieAsString = restoreMyCookieString();

and try to parse it:

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

now myCookieAsStringNow.toString(); produces


Domain and path parts are just gone. The reason: parse method is case sensitive to words like “domain” and “path”.
Possible workaround: provide another toString() method like:

public static String httpCookieToString(HttpCookie httpCookie) {
    StringBuilder result = new StringBuilder()

    if(!TextUtils.isEmpty(httpCookie.getDomain())) {
        result.append("; domain=")
        result.append("; path=")

    return result.toString();

I find it funny (especially, for classes like java.net.HttpCookie which are aimed to be used by a lot and lot of people) and I hope it will be useful for someone.


With a regular expression like :


you can parse a cookie like this :

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

in a few lines of code.


If you happen to have Netty HTTP codec installed, you can also use io.netty.handler.codec.http.cookie.ServerCookieDecoder.LAX|STRICT. Very convenient.


The advantage of Yanchenko’s approach with Apache Http client is that is validates the cookies consistent with the spec based on the origin. The regular expression approach won’t do that, but perhaps you don’t need to.

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);
        return cookieList;

I’ve attached a small example using yanchenkos regex. It needs to be tweaked just a little. Without the ‘?’ quantity modifer on the trailing ‘;’ the trailing attribute for any cookie will not be matched. After that, if you care about the other attributes you can use Doug’s code, properly encapsulated, to parse the other match groups.

Edit: Also, note ‘*’ qualifier on the value of the cookie itself. Values are optional and you can get cookies like “de=”, i.e. no value at all. Looking at the regex again, I don’t think it will handle the secure and discard cookie attributes which do not have an ‘=’.


CookieManager cookieManager = new CookieManager();
        HttpCookie cookie = new HttpCookie("lang", "en");
        cookie.setDomain("Your URL");

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


        val headers = ..........

        val headerBuilder = Headers.Builder()

        headers?.forEach {
            val values = it.split(";")
            values.forEach { v ->
                if (v.contains("=")) {
                    headerBuilder.add(v.replace("=", ":"))

        val headers = headerBuilder.build()