Cookie和Session

Cookie和Session是什么

Cookie和Session是两种会话数据的保存方式。其中,Cookie是客户端技术,Session是服务端技术。

两者具体的类封装在javax.servlet.http(时代变了)jakarta.servlet.http包中,依赖jakarta.servlet-api包即可使用jakarta.servlet.http下的类。

  1. 存储位置
    存储在客户端,一般保存在本地用户目录下的appdata

  2. 生命周期
    默认会话结束后消失(存于内存中)。

    通过setMaxAge(int time)可以设置cookie的有效期(单位是s,存到硬盘):

    • 默认值为-1
    • 如果设为0,立即删除
  3. 缺陷
    大小和数量限制:一般每个站点大约能保存20个cookie,大小限制在4kb以内。浏览器一般有300个cookie上限。
    数据安全性问题:http请求中的cookie是明文传递的。

  4. 以存储网站的上次访问时间为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决中文乱码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html");

PrintWriter out = resp.getWriter();

// 从客户端获取Cookie
Cookie[] cookies = req.getCookies();

// 判断cookies是否存在
if (cookies != null) {
out.write("你上次访问的时间是:");

for (Cookie cookie : cookies) {
if (cookie.getName().equals("lastLoginTime")) {
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
SimpleDateFormat dateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance();
out.write(dateFormat.format(date));
break;
}
}
} else {
out.write("这是你第一次访问本站");
}

// 服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", Long.toString(System.currentTimeMillis()));
// 设置cookie过期时间,以秒为单位
cookie.setMaxAge(24 * 60 * 60);
resp.addCookie(cookie);
}
}

Session

服务器会自动每一个用户(浏览器)创建一个Session对象,一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。

服务器在自动创建Session的时候,会同时生成一个Cookie,存储sessionId

1
2
Cookie cookie = new Cookie("JSESSIONID", sessionId);
resp.addCookie(cookie);
  1. 存储位置
    保存于服务端。

  2. 使用场景

    • 保存登录用户的信息
    • 保存购物车信息
    • 其他在整个网站中经常会使用的数据
  3. 生命周期

    • 有效期30min,可以通过两种方式设置有效期:
      • setMaxInactiveTnterval(int time),单位是s
      • web.xml中配置session有效期,单位是min
    1
    2
    3
    <session-config>
    <session-timeout>time</session-timeout>
    </session-config>
    • 还可以通过HttpSession的invalidate()方法,手动使session失效
  4. 相关方法

    Session也能和ServletContext一样,实现不同Servlet之间的通信。并且该方式**优于利用ServletContext**。

1
2
3
4
5
6
7
8
9
10
11
String password = request.getParameter("password");
HttpSession session = request.getSession();

String name = (String)session.getAttribute("userName");
session.setMaxInactiveTnterval(30 * 60);

session.setAttribute("password", password);

session.removeAttribute("password");

session.invalidate();