Java登陆第三十天——Cookie和Session

发布时间 2023-12-27 22:20:44作者: ocraft

会话

会话就是客户端与服务器的一次交互。

HTTP是一种无状态协议

  • 无状态:服务端不会记录客户端信息。

有的时候,我们需要保存客户端的信息。

  • 对于登陆功能来说,保存客户端信息,可以避免客户端每访问都需要登陆一次

至此,会话管理诞生。

Cookie是一种客户端会话技术,并保存在客户端之中。

HttpServletResponse方法 描述
void addCookie(Cookie var1) 向客户端添加响应报文头
  • Cookie是键值对的数据。

  • 创建若干个Cookie对象,并通过addCookie()方法响应给客户端。

    • (Tomcat会自动把Cookie对象转为set-cookie响应头)
  • 客户端接收到set-cookie响应头后,会在下次请求资源时,以cookie请求头的方式携带

Cookie类常用方法

方法 描述
String getName() 获取Cookie的键
String getValue() 获取Cookie的值
void setMaxAge(int expiry) 设置Cookie的存活时间(秒)
void setPath(String uri) 设置Cookie仅生效地址
  • 仅生效地址:

    • 在该地址中才有效,其他的地址,该Cookie不会在请求头中。

栗子

TestServlet5

@WebServlet("/Test5")
public class TestServlet5 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //给客户端响应两个Cookie
        resp.addCookie(new Cookie("keyA","valueA"));
        resp.addCookie(new Cookie("keyB","valueB"));
    }
}

TestServlet5B

@WebServlet("/Test5B")
public class TestServlet5B extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //cookie可能为多个,所以返回值是Cookie数组
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){
            for (Cookie cookie : cookies) {
                String value = cookie.getValue();
                System.out.println(value);
            }
        }else {
            System.out.println("没有Cookie");
        }
    }
}

客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B

//控制台输出,先以无Cookie访问
没有Cookie

试验先Test5再访问Test5B

先请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5

并查看响应头
image

再请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B

//控制台输出
valueA
valueB

Cookie的时效性

Cookie会根据存活时间的长度被分为:会话级Cookie;持久化Cookie

会话级Cookie 持久化Cookie
服务端没指定Cookie存活时间 服务端指定了Cookie存活时间
Cookie存在内存中 Cookie存在硬盘中
Cookie在客户端关闭后就会自动释放 Cookie在硬盘中存活时间由服务器指定
Cookie到达指定时间会被释放

Session

Session是一种服务端会话技术,保存在服务端之中。

HttpServletRequest方法 描述
HttpSession getSession() 获取Session对象
  • 服务端会为个请求的客户端创建一个的Session对象

    • 同时会把Session对象的id以Cookie的形式保存在JSESSIONID中
  • 客户端创建完Session后,客户端会收到一个特殊的Cookie。

    • 键是JSESSIONID,值是Session对象的id
  • 客户端下次访问服务端,携带的Cookie中就包含JSESSIONID,服务端会根据JSESSIONID找到对应的Session对象

  • Session是域对象(下一篇文章介绍)

Session接口常用方法

方法 描述
String getId() 获取Session对象的id
boolean isNew() Session是否是新生成的
void setAttribute(String var1, Object var2) 往Session对象里存储键值对数据
Object getAttribute(String var1) 获取Session对象里存储的值

栗子

TestServlet5

@WebServlet("/Test5")
public class TestServlet5 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        //输出Session的ID和新旧   T新F旧
        System.out.println(session.getId());
        System.out.println(session.isNew());

        session.setAttribute("keyA","valueA");

    }
}

TestServlet5B

@WebServlet("/Test5B")
public class TestServlet5B extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        //输出Session的ID和新旧   T新F旧
        System.out.println(session.getId());
        System.out.println(session.isNew());

        System.out.println(session.getAttribute("keyA"));

    }
}

客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B

//控制台输出,先以无Session访问
84C99AA919BF34E18E3796AA3DEF807C
true
null

试验先Test5再访问Test5B

重启客户端

先请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5

//控制台输出,先以无Session访问
84C99AA919BF34E18E3796AA3DEF807C
true

再请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B

//控制台输出
84C99AA919BF34E18E3796AA3DEF807C
false
valueA

因为Session是在服务端内保存,重启才能保证第二次正常按预期运行。