第八章会话控制

为什么需要会话控制

Http是无状态的协议

  • HTTP 无状态 :服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
  • 无状态的意思换句话说,服务器记不住你,可能你每刷新一次网页,就要重新输入一次账号密码进行登录。这显然是让人无法接受的
  • 用生活中的例子来说
    • 比如我们A(服务器)这个人开了一家商店,A这个人有一个特点,就是非常健忘,它的记忆只能维持到一个用户提出购买请求,和服务结束这一段时间

带来的问题

  • 我们可能会有一些需求,比如我们需要区分不同请求-响应,请求响应是不是同一个用户发送的,比如用户购买的越多,折扣就越大,那我们就需要分辨出不同的请求响应之间的逻辑关系,所以引入cookie体系
  • 或者无状态态带来的现实问题:第一次请求是添加商品到购物车,第二次请求是结账;如果这两次请求服务器无法区分是同一个用户的,那么就会导致混乱
    • 通过会话跟踪技术来解决无状态的问题。

在这里插入图片描述

保持用户登录状态,背后的底层逻辑是:服务器在接收到用户请求的时候,有办法判断这个请求来自于之前的某一个用户。所以保持登录状态,本质上是保持**『会话状态』**

如何解决无状态的问题——Cookie

以生活举例子

img

  • Cookie:就相当于A(服务器)发给每个客户(客户端)的一个凭证,客户必须有保存这个凭证的责任(你丢了,我就不知道你是不是你了),也必须在每次接收服务的时候带着这个凭证(你不带,我也不知道你是不是你)
  • 发凭证:从服务器到客户端,所以肯定是在响应体中,Set-Cookie
  • 携带凭证:从客户端到服务器,所以肯定在请求体中 Cookie
  • 我说的是「一个」cookie 可以认为是一个变量,形如 name=value,但是服务器可以一次设置多个 cookie,所以有时候说 cookie 是「一组」键值对儿,这也可以说得通。

具体的实现

image-20221211215437628

使用HttpSession对象,将数据存入会话域就能保持会话状态。

HttpSession session = request.getSession();
session.setAttribute("user", user);

具体实例证明

//演示Cookie
public class Demo3 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session,如果获取不到,则创建一个新的
        Cookie cookie1=new Cookie("name","lsc");
        Cookie cookie2=new Cookie("age","22");
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }
}

第一次在浏览器上访问demo3

在这里插入图片描述

  • 我们看到了在服务器中设置的Cookie值我们返回给了服务端,存储在Response Headers——实现了对应的发凭证的操作

第二次在同一个浏览器上访问demo3

image-20221211221105721

  • 第二次浏览器发送demo3请求,我们的请求中的请求头中携带对应的Cookie值——完成了携带凭证

如果只靠单纯的Cookie存在的问题

  • 安全问题:如果我们把cookie完全交给客户端,我们服务器完全信任cookie,那么如果碰到恶意用户或者恶意程序进行修改伪造别人的cookie,那么是不安全的
  • 性能问题:我们也知道现在的很多网站功能很复杂,而且涉及很多的数据交互,比如说电商网站的购物车功能,信息量大,而且结构也比较复杂,无法通过简单的 cookie 机制传递这么多信息,而且要知道 cookie 字段是存储在 HTTP header 中的,就算能够承载这些信息,也会消耗很多的带宽,比较消耗网络资源。
    • 因为我们上面的Cookie只是为了让服务器知道我是谁

单纯Cookie导致问题的解决方法——Session

  • 解决方法:拆分保存数据,把敏感的数据保存到服务器的内部,cookie只携带不敏感的信息,通常来说就是一个卡号也就是我们的SessionID,也就引入我们的session机制

在这里插入图片描述

  • 就类似我们服务器来保存重要的数据(洗浴),客户端来拿着卡号去对应的柜子去取东西(我们的随身物品)

Session

  • Session:是保存在服务器的,专属某次会话的,一组数据,可以跨请求访问(生命周期是跨请求的),通常Session中保存的数据也可以视为name-value.,一般cookie设置session-id.这样客户端和服务器之间仍然使用cookie机制,只是cookie只传递id即可(cookie还是放在我们的请求头和响应头中的,存储的是session-id),大头数据全部保存在服务器

session的结构

在这里插入图片描述

  • session类似一个卡号对应着一个柜子的结构,然后一个柜子也是一个Map的结构,因为柜子要存储name:value

一些关于Session的API

  • request.getSession() -> 获取当前的会话,没有则创建一个新的会话

    • request.getSession(true) -> 效果和不带参数相同

    • request.getSession(false) -> 获取当前会话,没有则返回null,不会创建新的

./images

  • session.getId() -> 获取sessionID

  • session.isNew() -> 判断当前session是否是新的

  • session.getMaxInactiveInterval() -> session的非激活间隔时长,默认1800秒

    • session.setMaxInactiveInterval()设置最大的非激活间隔时长

    • 比如我们一些银行的网页,如果三分钟不操作,可能当前账号就需要重新登录

    • 为什么Session要设置时限

      • 用户量很大之后,Session对象相应的也要创建很多。如果一味创建不释放,那么服务器端的内存迟早要被耗尽。
    • 设置时限的难点

      • 从服务器端的角度,很难精确得知类似浏览器关闭的动作。而且即使浏览器一直没有关闭,也不代表用户仍然在使用。

./images

  • session.invalidate() -> 强制性让会话立即失效

Session的保存作用域

Demo4资源

//演示向HttpSession保存数据
public class Demo4 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().setAttribute("uname","lina");
    }
}

Demo5资源

public class Demo5 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object unameObj = request.getSession().getAttribute("uname");
        System.out.println(unameObj);
    }
}
  • 我们在同一个浏览器先去访问Demo4,然后再去访问我们的Demo5,发现输出了lina
  • 我们在一个浏览器去访问Demo4,然后换一个浏览器访问Demo5,发现输出的值是null
  • 说明我们的session保存的信息作用域是可以跨请求的,session保存作用域是和具体的某一个session对应的

image-20221211223838035

  • void session.setAttribute(k,v)
  • Object session.getAttribute(k)
  • void removeAttribute(k)

Cookie时效性

  • 会话级Cookie
    • 服务器端并没有明确指定Cookie的存在时间
    • 在浏览器端,Cookie数据存在于内存中
    • 只要浏览器还开着,Cookie数据就一直都在
    • 浏览器关闭,内存中的Cookie数据就会被释放
  • 持久化Cookie
    • 服务器端明确设置了Cookie的存在时间
    • 在浏览器端,Cookie数据会被保存到硬盘上
    • Cookie在硬盘上存在的时间根据服务器端限定的时间来管控,不受浏览器关闭的影响
    • 持久化Cookie到达了预设的时间会被释放

服务器端返回Cookie时附带过期时间的响应消息头如下

image-20221211225923306

服务器通知浏览器删除Cookie时的响应消息头如下

image-20221211230029495

会话和持久化Cookie对比

image-20221211230109363

Cookie的domain和path

上网时间长了,本地会保存很多Cookie。对浏览器来说,访问互联网资源时不能每次都把所有Cookie带上。浏览器会使用Cookie的domain和path属性值来和当前访问的地址进行比较,从而决定是否携带这个Cookie。

image-20221211230159958

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

库里不会投三分

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值