目录
Cookie
什么是Cookie?
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户的各自的浏览器.当用户使用浏览器去访问服务器中的web资源时,以后每次请求都将之前保存的共享数据发送到服务器.
作用
实现会话跟踪.
实现原理
- 客户端发送请求给服务器
- 服务器发送响应头set-cookie并携带数据给客户端
- 客户端将响应头携带的数据保存到客户端浏览器中
- 下一次请求客户端会使用消息头cookie数据携带给服务器
- 服务器获取消息头中的数据
流程:
- 首先客户端填写用户名和密码登录请求服务器, 服务器接收到请求参数(用户名或密码)之后将它们保存到Cookie中
(Cookie c = new Cookie("用户名 key", "value")
, 多个key-value,创建多个cookie, 将cookie对象通过response.addCookie(c)
写回到客户端,。当下次客户端要登录的时候, 就直接携带请求头中的cookie内容进行登录即可!
Cookie的操作
-
创建Cookie对象
Cookie cookie = new Cookie(String name, String value);
name: 当前Cookie取的唯一名字.
value: 存储在Cookie的共享数据,只能是字符串类型.Cookie cookie = new Cookie("currentName", "ZYGui");
-
把Cookie放入响应中,响应给浏览器,把共享的数据存储到浏览器中
response.addCookie(cookie);
-
获取Cookie及里面的数据
Cookie[] cs = request.getCookie();
-
修改Cookie中指定的属性名的属性值
A. 重新创建一个新的Cookie,创建一个同名的新的Cookie.
Cookie c = new Cookie("currentName", "AAA");
B. 先获取到要修改的Cookie对象,再调用setValue(String newValue)
重新设置
注意:修改Cookie中的数据,需要再次发送给浏览器.response.addCookie(c);
-
操作Cookie的生命周期,默认是在关闭浏览器的时候销毁
- 会话Cookie: 关闭浏览器之后,Cookie就销毁了. 缺省情况
- 持久化Cookie: Cookie可以保存指定的时间段.
设置Cookie的最大存活时间:cookie.setMaxAge(int seconds);
seconds = 0: 删除Cookie;
seconds < 0: 会话Cookie
seconds > 0: 存储指定的秒数.
-
删除Cookie
cookie.setMaxAge(0);
-
Cookie 中的key和value不支持中文
- 先对中文字符串进行编码
- 获取之后在进行解码
- 先对中文字符串进行编码
Cookie共享问题
-
Cookie的路径
Cookie在创建的时候,会根据当前的Servlet的相对路径
来设置自己的路径
Servlet的相对路径(url-pattern最后的/前面的路径)
比如Servlet的url-pattern为/cookie/login,相对路径:/cookie/
问题: 此时,只有在访问路径为/cookie/下面的资源的时候,才会将该Cookie发送到服务器
解决方案:
设置Cookie的路径
void setPath(String uri)
cookie.setPath("/项目名称");
表示当前应用中的所有的资源都能够共享该Cookie信息
为什么要设置路径,当访问某些页面时,不希望携带cookie.此时就可以设置cookie的携带路径.
路径写法: /项目名称, 所有项目中添加cookie,访问时都会携带.
设置 /项目名称/p, 此时只访问/p时,才携带cookie,其他路径不携带. -
域范围
在多个应用之间实现数据共享,那么需要设置域范围,比如:news.baidu.com
map.baidu.comcookie.setDomain("baidu.com");
Cookie的缺陷
- 获取Cookie信息很麻烦
- Cookie不支持中文
- 一个Cookie只能存储一个字符串类型的数据
- Cookie的在浏览器中有数量的限制
一个浏览器对一个站点最多存储20Cookie信息
一个浏览器最多只能够存储300个Cookie - 共享数据时保存在浏览器中的,容易造成数据的泄露(不安全)
最好的解决方案: 将数据保存在服务端(Session)
Code
- LoginServlet
@WebServlet("/cookie/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String username = request.getParameter("username"); // 创建Cookie,存储数据 Cookie c = new Cookie("currentName", username); c.setPath("/"); // 整个应用中都可以共享 // c.setMaxAge(15); 设置15秒后cookie销毁 // 把cookie响应给浏览器 response.addCookie(c); out.println("欢迎:"+username+"<br>"); out.println("<a href='/abc/list'>收件箱</a>"); }
- ListServlet
@WebServlet("/abc/list") public class ListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String username = ""; // 获取Cookie的内容 Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); if ("currentName".equals(name)) { username = value; } } } out.println("欢迎:" + username + "<br>"); for (int i = 0; i < 5; i++) { out.println("<a href='/cookie/get'>一封邮件</a><br>"); } }
- GetServlet
@WebServlet("/cookie/get") public class GetServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String username = ""; // 获取Cookie的内容 Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); if ("currentName".equals(name)){ username = value; } } out.println("欢迎:"+username+"<br>"); out.println("欢迎收看!"); }