Web基础-Cookie和Session

本文深入讲解了Cookie与Session的工作原理和技术细节,包括Cookie的创建、获取、修改、生命周期控制及路径设置;Session的创建获取、域数据存取、生命周期控制等。并通过实际代码示例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Cookie

1.1 什么是Cookie
  • 服务器通知客户端保存键值对的一种技术,是由servlet发送到Web浏览器的少量信息,然后发送回服务器
  • 客户端有了Cookie 后,每次请求都发送给服务器
  • 每个 Cookie 的大小不能超过4kb

tips:

  • 为了下面章节的展现,基本页面和代码如下:

在这里插入图片描述

// BaseServlet类
public abstract class BaseServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决相应中文乱码问题
        resp.setContentType("text/html; charset=UTF-8");
        String action = req.getParameter("action");
        try {
            // 获取action业务鉴别字符串,获取相应的业务方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            // 调用目标业务方法
            method.invoke(this, req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
// cookie.html
// 加上了<base href="http://localhost:8080/book/">
<ul>
    // 这里发送给cookieServlet是get请求,所以在BaseServlet中实现的是doGet方法
    // 请求已发送就会去调用cookieServlet的父类BaseServlet的doGet方法,然后通过反射进行action中相应方法的调用
    <li><a href="cookieServlet?action=createCookie" target="target">Cookie的创建</a></li>
    <li><a href="cookieServlet?action=getCookie" target="target">Cookie的获取</a></li>
    <li><a href="cookieServlet?action=updateCookie" target="target">Cookie值的修改</a></li>
    <li>Cookie的存活周期</li>
    <li>
        <ul>
            <li><a href="cookieServlet?action=defaultLife" target="target">Cookie的默认存活时间(会话)  				  </a>
            </li>
            <li><a href="cookieServlet?action=deleteNow" target="target">Cookie立即删除</a></li>
            <li><a href="cookieServlet?action=life3600" target="target">Cookie存活3600秒(1小时)</a>		   		</li>
        </ul>
    </li>
    <li><a href="cookieServlet?action=testPath" target="target">Cookie的路径设置</a></li>
    <li><a href="" target="target">Cookie的用户免登录练习</a></li>
</ul>
1.2 服务器创建cookie
  • 创建cookie的过程:

在这里插入图片描述

public class cookieServlet extends BaseServlet {
 protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     // 1.创建cookie对象
     Cookie cookie = new Cookie("key1", "value1");
     // 2. 通知客户端保存cookie
     resp.addCookie(cookie);
     resp.getWriter().write("cookie创建成功");  // cookie.html的框中显示cookie创建成功
 	}
}

在这里插入图片描述

1.3 服务器获取cookie
  • 获取cookie过程:

在这里插入图片描述

protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie[] cookies = req.getCookies();
    for (Cookie cookie : cookies) {
        // 返回cookie的名称和值
        // cookie.html的框中显示所有cookie的信息
        resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "]");
    }
}
1.4 服务器修改Cookie值
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.先创建一个要修改的同名的Cookie对象,然后赋予新的值
    Cookie cookie = new Cookie("key1", "newValue");
    // 2.通知客户端保存修改
    resp.addCookie(cookie);
    // cookie.html的框中显示该输出
    resp.getWriter().write("cookie修改成功");
    
    // 也可以先根据key先找到要修改的cookie,然后调用setValue()方法赋于新的Cookie值
}
1.5 Cookie的生命控制
  • 生命控制:如何管理Cookie 什么时候被销毁(删除),使用setMaxAge()方法进行控制,不同参数表示不同含义:
    • 正数:表示在指定的秒数后过期
    • 负数:表示浏览器一关,Cookie 就会被删除(默认值是-1)
    • 零:表示马上删除Cookie

在这里插入图片描述

protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("defalutLife", "defaultLife");
    cookie.setMaxAge(-1);  //设置存活时间
    resp.addCookie(cookie);
}
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("life3600", "life3600");
    cookie.setMaxAge(60 * 60); // 设置 Cookie 一小时之后被删除
    resp.addCookie(cookie);
    resp.getWriter().write("已经创建了一个存活一小时的 Cookie");
}
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    // 先找到你要删除的 Cookie 对象
    Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
    if (cookie != null) {
        // 调用 setMaxAge(0);
        cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
        // 调用 response.addCookie(cookie);
        resp.addCookie(cookie);
        resp.getWriter().write("key4 的 Cookie 已经被删除");
    }
}
1.6 设置Cookie有效路径
  • Cookie的path属性可以有效的过滤哪些Cookie可以发送给服务器,哪些不发。该属性是通过请求的地址来进行有效的过滤:

在这里插入图片描述

protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Cookie cookie = new Cookie("path1", "path1");
    // getContextPath() ===>>>> 得到工程路径
    cookie.setPath( req.getContextPath() + "/abc" ); // ===>>>> /工程路径/abc
    resp.addCookie(cookie);
    resp.getWriter().write("创建了一个带有Path路径的 Cookie");
}

​ 此时输入http://localhost:8080/book/cookie.html点击cookie的路径设置后,再按F12查看Application的内容时是没有path1这个cookie的,但是可以在检查Network发送给服务器的cookie时可以看见该cookie:

在这里插入图片描述

​ 当输入http://localhost:8080/book/abc/cookie.html时便可以查询到返回给客户端的该cookie:

在这里插入图片描述

1.7 Cookie实践
  • 实现免输入用户名登录:

在这里插入图片描述

// login.html
<body>
    <form action="http://localhost:8080/book/loginServletCookie" method="get">
        // value用于显示保存在客户端的cookie的值(保存在客户端的cookie用于显示,而在请求头中的cookie用于发送给服务器)
        用户名:<input type="text" name="username" value="${cookie.username.value}"> <br>  
        密码:<input type="password" name="password"> <br>
        <input type="submit" value="登录">
    </form>
</body>
public class LoginServletCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if ("psj".equals(username) && "123456".equals(password)) {
            // 登录 成功
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7);//当前Cookie一周内有效
            resp.addCookie(cookie);
            System.out.println("登录成功");
        } else {
            // 登录 失败
            System.out.println("登录失败");
        }
    }
}

​ 第一次输入http://localhost:8080/book/login.jsp后,键入用户名和密码,此时输出相应的登录信息。第二次输入相同网址时,显示在页面的表单中的用户名会自动显示上一次输入的psj。因为第二次输入网址后,客户端发送给服务器的请求头中会有第一次请求服务器返回的cookie:

在这里插入图片描述


2.Session

2.1 什么是 Session
  • Session是一个接口(HttpSession)
  • 一个会话,它是用来维护一个客户端和服务器之间关联的一种技术
  • 每个客户端都有自己的一个Session会话
  • 经常被用来保存用户登录之后的信息
  • Cookie保存在客户端,而Session保存在服务器端

tips:

  • 为了下面章节的展现,基本页面和代码如下:
// session.html
// 加上了<base href="http://localhost:8080/book/">
<body>
   <iframe name="target" width="500" height="500" style="float: left;"></iframe>
   <div style="float: left;">
      <ul>
         <li><a href="sessionServlet?action=createOrGetSession" target="target">Session的创建和获取(id号、是否为新创建)</a></li>
         <li><a href="sessionServlet?action=setAttribute" target="target">Session域数据的存储</a></li>
         <li><a href="sessionServlet?action=getAttribute" target="target">Session域数据的获取</a></li>
         <li>Session的存活</li>
         <li>
            <ul>
               <li><a href="sessionServlet?action=defaultLife" target="target">Session的默认超时及配置</a></li>
               <li><a href="sessionServlet?action=life3" target="target">Session3秒超时销毁</a></li>
               <li><a href="sessionServlet?action=deleteNow" target="target">Session马上销毁</a></li>
            </ul>
         </li>
         <li><a href="" target="target">浏览器和Session绑定的原理</a></li>
      </ul>
   </div>
</body>
// BaseServlet类
public abstract class BaseServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 和Cookie章节一致
}
2.2 Session创建和获取
  • 创建和获取使用的API都是request.getSession()
    • 第一次调用时是创建Session
    • 再次调用时是获取前面创建好的Session
    • 要区分是刚创建的还是之前创建的,可以使用isNew()方法判断
  • 每个会话都有一个身份证号(ID值),该ID是唯一的,可以通过getId()方法查看
protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 创建和获取Session会话对象
    HttpSession session = req.getSession();
    // 判断当前Session会话,是否是新创建出来的
    boolean isNew = session.isNew();
    // 获取Session会话的唯一标识id
    String id = session.getId();

    resp.getWriter().write("得到的Session,它的id是:" + id + " <br /> ");
    // 点击Session的创建和获取(id号、是否为新创建)打印true,再次点击时打印false
    resp.getWriter().write("这个Session是否是新创建的:" + isNew + " <br /> ");
    
}
2.3 Session域数据的存取
// 往Session中保存数据
protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 点击Session域数据的存储打印已经往Session中保存了数据
    req.getSession().setAttribute("key1", "value1");
    resp.getWriter().write("已经往Session中保存了数据");
}
// 获取Session域中的数据
protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Object attribute = req.getSession().getAttribute("key1");
    // 点击Session域数据的获取打印从Session中获取出key1的数据是value1
    resp.getWriter().write("从Session中获取出key1的数据是:" + attribute);
}
2.4 Session 生命周期控制
  • setMaxInactiveInterval(int interval):设置 Session 的超时时间(以秒为单位),超过指定的时长,Session就会被销毁
    • interval为正数的时候,设定 Session 的超时时长。
    • interval为负数表示永不超时(极少使用)
  • getMaxInactiveInterval():获取Session的超时时间
  • invalidate():让当前Session会话马上超时无效
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 获取了Session的默认超时时长
    int maxInactiveInterval = req.getSession().getMaxInactiveInterval();
    // 点击Session的默认超时及配置后打印1800秒
    resp.getWriter().write("Session的默认超时时长为:" + maxInactiveInterval + " 秒 ");
}
protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先获取Session对象
    HttpSession session = req.getSession();
    // 设置当前Session3秒后超时
    session.setMaxInactiveInterval(3);
    // 点击Session3秒超时销毁后当前Session已经设置为3秒后超时
    resp.getWriter().write("当前Session已经设置为3秒后超时");
}

protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先获取Session对象
    HttpSession session = req.getSession();
    // 让Session会话马上超时
    session.invalidate();
    // 点击Session马上销毁后打印Session已经设置为超时(无效)
    resp.getWriter().write("Session已经设置为超时(无效)");
}

tips:

  • 为在 Tomcat 服务器的配置文件web.xml中默认有以下的配置,在当前项目的web.xml文件中可以添加该配置对该项目的所有Session进行修改:
<session-config>
	<session-timeout>30</session-timeout>
</session-config>
  • Session的超时是指两次请求之间的最大间隔时长。假设调用life3方法设置了超时时长为3秒,意味着当前Session在3秒后会被销毁,即点击Session的创建和获取(id号、是否为新创建)应该由false变为true(变true的原因是点击后调用了req.getSession()创建了一个新Session),但实际上连续点击后还是显示false。因为连续点击时每次请求的时长小于3秒,并没有超时,所以原来的Session没有销毁,如果等一段时间后点击才会显示true
2.5 浏览器和Session之间的关联
  • Session 技术的底层其实是基于 Cookie 技术来实现的。这也就解释了为什么即使给Session设置了很长的超时时长后,一关闭浏览器Session还是会被销毁,因为浏览器一关,Cookie 就会被删除(默认,可以使用setMaxAge()方法进行控制),没有了该Cookie意味着无法携带原来的SessionID给服务器去查找,相当于被删除

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值