Java 11中HttpCookie.parse解析含JSON的Cookie时抛IllegalArgumentException
问题根源
Java 11的HttpCookie.parse()方法内部通过splitMultiCookies()拆分多Cookie内容,该方法会将所有未被引号包裹的逗号视为Cookie分隔符。当Cookie值包含JSON结构(如{"key":"value","key2":"value2"})时,JSON内部的逗号会被误判为Cookie分隔符,导致原始Cookie被拆分为两个无效部分,最终触发解析异常。
解决方法
1. 预处理Cookie字符串,规范包裹JSON值
根据Cookie规范,包含逗号、分号等特殊字符的Cookie值需要用双引号包裹。你可以手动给JSON格式的Cookie值添加双引号后再解析:
String rawCookie = "your_cookie_name={\"key\":\"value\",\"key2\":\"value2\"}; Max-Age=3600; Path=/; Secure; HttpOnly"; // 给JSON值添加双引号,避免内部逗号被误拆分 String processedCookie = rawCookie.replace("your_cookie_name={", "your_cookie_name=\"{") .replace("}; Max-Age", "\"}; Max-Age"); List<HttpCookie> cookies = HttpCookie.parse(processedCookie);
这种方法适合Cookie名称固定的场景,简单直接。
2. 自定义Cookie拆分逻辑
如果Cookie名称不固定或JSON结构复杂,可以实现自定义拆分逻辑,跳过JSON内部的分隔符:
public static List<String> splitCookiesSafely(String cookieHeader) { List<String> cookies = new ArrayList<>(); StringBuilder current = new StringBuilder(); int braceDepth = 0; boolean inQuotes = false; for (char c : cookieHeader.toCharArray()) { // 仅当不在JSON结构或引号内时,才将分号视为Cookie分隔符 if (c == ';' && braceDepth == 0 && !inQuotes) { cookies.add(current.toString().trim()); current.setLength(0); } else { current.append(c); // 跟踪引号状态 if (c == '"') { inQuotes = !inQuotes; } // 跟踪JSON对象的括号深度 else if (c == '{' && !inQuotes) { braceDepth++; } else if (c == '}' && !inQuotes) { braceDepth--; } } } // 添加最后一个Cookie if (current.length() > 0) { cookies.add(current.toString().trim()); } return cookies; }
之后遍历拆分后的单个Cookie字符串,调用HttpCookie.parse()解析即可。
3. 切换到第三方Cookie解析库
如果不想自行处理兼容性问题,可以使用Apache HttpClient的Cookie解析工具,它对特殊字符的处理更宽松:
import org.apache.http.impl.cookie.BasicCookieParser; import org.apache.http.cookie.Cookie; String rawCookie = "your_cookie_name={\"key\":\"value\",\"key2\":\"value2\"}; Max-Age=3600; Path=/; Secure; HttpOnly"; BasicCookieParser parser = new BasicCookieParser(); List<Cookie> cookies = parser.parse(rawCookie, null);
内容的提问来源于stack exchange,提问作者ajs
相关产品推荐
相关产品推荐

