java获取cookie

Java里获取Cookie,最直接的方式就是调用`request.getCookies()`。这个方法返回一个`Cookie[]`数组,遍历它,按名字比对,就能拿到你要的值。就这么简单,但实际项目里,坑往往不在“获取”这一步,而在你拿到的时机和容器实现上。 看代码。假设你在Servlet或者Spring MVC的Controller里,直接注入`HttpServletRequest`: ```java Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("sessionId".equals(cookie.getName())) { String value = cookie.getValue(); // 处理你的逻辑 break; } } } ``` 注意那个`null`判断。别省。如果客户端没带任何Cookie,`getCookies()`返回的是`null`而不是空数组。你直接for循环,立刻抛`NullPointerException`。这是我见过最多的低级错误,没有之一。 群里有个哥们儿上周就栽在这上面,他写了个过滤器想统一校验登录态,结果一上线,所有没带Cookie的静态资源请求全炸了。日志刷了一屏NPE,他盯着屏幕愣了三分钟,最后发现是没判空。真事儿。 再说说路径问题。Cookie有`path`属性,容器在返回Cookie给应用时,通常只返回匹配当前请求路径的Cookie。如果你在`/admin`下设置了一个Cookie,但没指定`path`,默认是`/admin`,那你在`/user`页面调用`getCookies()`,根本看不到它。这不是Java的错,是HTTP协议本身的设计。所以调试时,先确认Cookie的`path`对不对,别老怀疑代码逻辑。 还有`HttpOnly`。这个属性你从服务端读不到,它只是告诉浏览器别让JavaScript碰这个Cookie。但如果你用`request.getCookies()`在服务端遍历,你依然能拿到`HttpOnly`的Cookie,因为服务端和浏览器是两码事。这点很多人混淆,以为设置了`HttpOnly`服务端就“隐藏”了,其实完全不是。服务端始终能看到所有发过来的Cookie头。 获取Cookie的另一个实用技巧是处理多个同名Cookie。HTTP规范允许同名Cookie存在,只是路径不同。但`request.getCookies()`会原样返回所有,不帮你合并。你得自己按`path`优先级去判断,或者干脆在写入时就保证名字唯一。我一般建议后者,省心。 如果你用的是Spring,还有个简便方法——`@CookieValue`注解: ```java @GetMapping("/test") public String test(@CookieValue(value = "sessionId", defaultValue = "") String sessionId) { // 直接用 } ``` 它能帮你自动转类型,还能设置默认值。但注意,如果Cookie不存在且你没设`defaultValue`,会抛`MissingRequestCookieException`。所以要么给默认值,要么把`required`设为`false`。 最后说个偏门但真实存在的场景:某些反向代理或负载均衡器会改写Cookie头,比如加上前缀或压缩。你调`getCookies()`拿到的可能是被代理处理过的版本。这时候别慌,先抓包看原始HTTP头,确认是代理的问题还是你代码的问题。我遇到过Nginx配置了`proxy_cookie_path`后,应用读到的Cookie名多了个前缀,排查了半天,最后发现是运维改的配置。 总结一下,获取Cookie本身三行代码完事,真正的复杂度在边界情况:判空、路径匹配、同名处理、代理改写。把这些都想到了,你才算真正会拿Cookie。