从Cookie到Session: Servlet API中的会话管理详解

这篇具有很好参考价值的文章主要介绍了从Cookie到Session: Servlet API中的会话管理详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. Cookie与Session

1. Cookie与Session

首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制, 要清楚 Cookie 是从哪里来, 要到哪里去.

Cookie 是来自于服务器的, 通过响应报文中的 Set-Cookie 字段将数据返回保存在浏览器本地的; 后续当浏览器访问服务器的时候, 就会把本地的 Cookie 通过 HTTP 请求给带过去.

HTTP 协议是 “无状态” 协议, 这里的 “无状态” 指的是默认情况下 HTTP 协议的客户端和服务器之间的每次通信, 和它之前之后的通信是没有直接的联系的, 但是在实际开发中多次通信是需要建立起 “上下文” 联系的, 用户发起请求通过 Cookie 字段将 Cookie 中的内容发送到服务器, 服务器就能知道和客户端的上一次通信处于什么样的状态, 此时 Cookie 这种机制就有了用武之地, 最典型的一种应用, 就是使用 Cookie 来标识用户的身份信息.

常见的网站登录, 比如淘宝, 我们登录一次网站后, 后续再使用访问淘宝的其他页面, 是不需要再次登录的, 还有自动登录功能, 隔了一段时间再次访问淘宝网站, 我们会发现此时并不需要再次输入账号密码登录, 网站就会自动地帮我们登录.

为了实现这种网站自动登录和访问的功能, 就可以将 SessionCookie 搭配使用, 在用户在输入账号密码登录在淘宝服务器查询数据库验证通过后, 服务器会创建一个 Session 会话来保存当前用户的数据和信息, 并生成一个 Cookie 数据.

该 Session 中包含用户一些关键身份信息, 服务器会给这个用户分配一个表示身份的序号, 是具有唯一性的整数/字符串 (SessionId), 服务器使用类似于 Hash 表这样的结构把身份序号 (SessionId) 作为 Key, 身份信息 (Session) 作为 Value 存储起来, 这样的每一对键值对就是一个 Session 会话.

服务器给客户端返回的 Cookie 里面就包含 SessionId, 浏览器就会在本地将这个 Cookie 储存起来, 后续浏览器发送请求的时候就会带上这个 Cookie, 服务器收到 Cookie 中的身份序号后, 就会查询 Session 会话表, 如果存在就会可以正常访问, 不用重复的输入账号与密码, 否则就需要用户重新输入账号密码进行登录.

从Cookie到Session: Servlet API中的会话管理详解

有时候我们会发现登录网站后隔一段时间再次登录, 会出现让我们再次输入账号密码的情况, 此时就是登录状态失效过期了, 这种情况可能是可能是客户端把 Cookie 删了, 也可能是服务器这把对应的身份信息删了.

举个生活中里例子, 去医院看病需要先挂号, 如果你是第一次去这家医院的, 就会给你新办理一个就诊卡, 这个就诊卡里面就含有你的一些关键身份信息, 并且会在医院的服务器上新建一个档案, 拿着这个就诊卡, 你就可以在该医院的各个科室进行刷卡, 如果你之前在这个医院有就诊记录, 你一刷卡就可以查询到你所有在医院的就诊信息.

这个例子中的就诊卡就相当于是 Cookie, 上面有你最基本的身份信息, 在医院服务器上所储存有关你的详细信息, 就相当于一个 Session 会话, 服务器上包含很多用户的就诊信息, 即会有多个 Session 会话对应不同的用户.

🎯要注意理解 Cookie 和 Session 之间的区别和关联.

  • 关联: 在网站登录功能中可以搭配使用.
  • 区别:
  1. Cookie 是客户端的存储机制, Session 是服务器的存储机制.
  2. Cookie 里面可以存各种键值对 (还可以存除 SessionId 以外的), Session 则专门用来保存用户信息.
  3. Cookie 完全可以单独使用, 不搭配 Session (实现非登录的场景), Session 也可以不搭配 Cookie (手机 App 登录服务器, 此时也需要 Session, 但这里没有 Cookie 的概念, Cookie 和浏览器强相关的).
  4. Cookie 是 HTTP 协议中的一个部分, Session 则可以和 HTTP 无关 (TCP, WebSocket …也可以用 Session).

2. Servlet会话管理操作

HttpServletRequest 类中, 可以使用 getSession 来获取或者创建会话, getCookies 可以获取请求中的 Cookie 列表.

方法 描述
HttpSession getSession() 在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
Cookie[] getCookies() 返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把 Cookie 中的格式解析成键值对.

调用 getSession 方法所做的事情:

getSession 有一个 boolean 类型的参数, 如果参数是 true, 它有如下行为:

  1. 读取 cookie 里的 sessionId 字段.
  2. 根据 sessionId 来查询对应的 HttpSession 对象在服务器上是否存在.
  3. 如果不存在, 就创建一个新的会话, 即创建一个新的 HttpSession 对象, 并生成一个唯一的 sessionId, 会以新生成的 sessionId 作为 Key, 生成的 HttpSession 对象作为 Value, 以键值对形式储存到类似于 Hash 的结构中, 然后将 sessionId 设置到响应报文中的 set-Cookie 字段返回给浏览器.
  4. 如果存在就直接返回查询到的 HttpSession 对象.

如果参数是 false, 行为如下:

  1. 读取 cookie 里的 sessionId 字段.
  2. 根据 sessionId 来查询对应的 HttpSession 对象在服务器上是否存在.
  3. 如果不存在, 直接返回 null.
  4. 如果存在就直接返回查询到的 HttpSession 对象.

总之就是, getSession 的参数为 true 时允许创建 Session 会话, 为 false 时不允许创建 Session 会话.

🍂关于HttpSession
这个对象也可以看作是一个哈希表, 是以键值对的形式存储数据的, 并且允许程序员在对象中储存任意的键值对数据, 但是 Key 必须是 String 类型, Value 的类型是 Object, 设置就比较随意了.

该类中提供了两个方法可以用来获取该对象中键值和设置键值对.

方法 描述
Object getAttribute(String name) 查询 session 会话中指定键的键值, 查不到则返回 null.
void setAttribute(String name, Object value) 绑定一个键和值到该 session 会话中
boolean isNew() 判定当前是否是新创建出的会话

所以服务器组织会话的方式就如下图:

从Cookie到Session: Servlet API中的会话管理详解

二. 登录逻辑的实现

我们这里模拟实现一个登录的功能, 很多网站都会让你先登录, 才能使用其中的一些功能, 我们这里实现登录完成之后, 就跳到另一个主页, 不进行登录的话, 这个主页是不能被访问的.

所以, 我们这里主要涉及到两个页面, 第一个是登录页面, 第二个是登录成功后要跳转的主页面.

登录页面包含两个输入框 (用来输入用户名和密码) 和一个登录按钮, 点击登录按钮就会发起一个 HTTP 请求, 服务器处理这个请求的时候就会验证用户名和密码, 验证通过就会跳转到主页, 主页就简单的显示出当前用户的用户名就行了.

实现整这里的逻辑就涉及到两个 Servlet 类:

  1. 处理登录的 LoginServlet, 用来判段用户名和密码, 登录成功和登录失败的情况.
  2. 构造主页面的 IndexServlet, 用来构造登录成功的主页.

从Cookie到Session: Servlet API中的会话管理详解

1️⃣第一步, 约定前后端接口.
我们需要实现两套交互逻辑, 一是登录跳转, 二是获取主页.
登录跳转, 这里只是示范作用, 约定只有一个用户, 就不加数据库的逻辑了.

约定用户名就是 zhangsan, 密码就是 123, 使用 POST 请求, 响应采用 302 重定向.
从Cookie到Session: Servlet API中的会话管理详解
获取主页, 采用 GET 请求, 响应返回一个页面.
从Cookie到Session: Servlet API中的会话管理详解
2️⃣第二步, 编写前端交互页面

目标页面如下:
从Cookie到Session: Servlet API中的会话管理详解
这里的场景很简单. 就直接使用 form 表单构造来 Post 请求了.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    <form action="login" method="post">
        <span>用户名</span>
        <input type="text" name="username">
        <span>密码</span>
        <input type="password" name="password">
        <input type="submit" value="登录">
    </form>
</body>
</html>

3️⃣第三步, 编写后端处理代码

对于登录跳转主页的 Post 请求处理思路如下:

  • 从请求中获取用户名和密码.
  • 验证用户名和密码是否正确, 正常来说是要查询数据库的, 这里就不添加数据库的逻辑了.
  • 如果验证通过, 创建会话, 并将 username 和主页被访问的次数数据添加到会话中 (保存必要的用户信息), 创建好会话后, 重定向到主页index.
  • 如果验证不通过, 重定向到登录页面.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        resp.setCharacterEncoding("utf8");
        // 获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 验证用户名密码是否正确
        // 这里约定合法的用户名为zhangsan,密码是123

        if (username.equals("zhangsan") && password.equals("123")) {
            // 登陆成功!!
            // 创建一个会话
            HttpSession session = req.getSession(true);
            // 把当前的用户名保存到会话中
            session.setAttribute("username", username);
            // 设置初始情况下登录成功访问主页的次数为0
            session.setAttribute("count", 0);
            // 重定向到主页
            resp.sendRedirect("index");
        } else {
            // 登陆失败!!
            // 重定向到 登陆页面
            System.out.println("用户名或者密码错误!");
            resp.sendRedirect("login.html");
        }
    }
}

获取主页的 GET 请求处理思路:

  • 获取会话 (请求中包含 sessionId, 会话是根据 sessionId 获取的)
  • 取出会话信息, 将主页返回次数加 1 并写回到会话信息中.
  • 返回一个简单的页面, 显示用户名和主页访问次数.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    // 重定向, 浏览器发起的是GET请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 先判定用户的登陆状态.
        // 如果用户还没登陆, 要求先登陆.
        // 已经登陆了, 则根据会话中的用户名, 将相关信息显示到页面上.
        HttpSession session = req.getSession(false);
        if (session == null) {
            // 未登录状态
            System.out.println("用户未登录!");
            // 重定向到登录页面
            resp.sendRedirect("login.html");
            return;
        }
        // 已经登陆, 取出会话信息
        String username = (String)session.getAttribute("username");
        Integer count = (Integer)session.getAttribute("count");
        // 访问次数加 1 后再写回到会话中
        count++;
        session.setAttribute("count", count);
        // 构造页面
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("<h3>欢迎您!" + username + "</h3> <h4>这个主页已经被访问了" + count + "次</h4>");
    }
}

抓包分析交互过程:
从Cookie到Session: Servlet API中的会话管理详解
第一次交互, 浏览器从服务器获取登录页面.

从Cookie到Session: Servlet API中的会话管理详解
第二次交互, 浏览器给服务器一个登录请求, 服务器返回响应, 重定向页面.

从Cookie到Session: Servlet API中的会话管理详解
第三次交互, 浏览器收到 302 重定向响应后, 再次向服务器发起请求, 访问主页.

从Cookie到Session: Servlet API中的会话管理详解

响应结果:

从Cookie到Session: Servlet API中的会话管理详解

用户名或者密码错误的情况下:

从Cookie到Session: Servlet API中的会话管理详解

从Cookie到Session: Servlet API中的会话管理详解

未登录直接访问的情况下:

从Cookie到Session: Servlet API中的会话管理详解

从Cookie到Session: Servlet API中的会话管理详解

这里关于 IDEA 集成的 Tomcat 环境有一些需要注意的点, 正常来说, 上面说的 sessionId 并不会一直存在下去, 比如 Tomcat 服务器重新启动的时候, 原来服务器在内存中维护的会话 Hash 表就应该没有了, 此时再次访问, 就应该出现 sessionld 查不到, 就被识别成 “未登录” 状态了, 但是有些版本 Smart Tomcat 为了方便程序猿调试程序, 会在停止服务器的时候把会话持久化保存, 并且在下次启动的时候自动把会话恢复到内存中, 在这种情况下会话是不丢失的.

但如果是手动部署程序到 Tomcat, 则会话默认还是在内存中, 重启服务器是会丢失的.文章来源地址https://www.toymoban.com/news/detail-479001.html

到了这里,关于从Cookie到Session: Servlet API中的会话管理详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 掌握JavaWeb开发的必备技能:Servlet、JSP、Cookie、Session、EL、JSTL详解 ~~~~B站老杜--Servlet-JSP-课堂笔记

    🚀🚀1. 什么时间直播? 晚上8:00到10:00 🚀🚀2. 每周直播几天? 3天(周一、周三、周五) 本周比较特殊:周四周五周六三天直播,从下周开始就是一三五直播。 🚀🚀3. 直播什么内容? 从JavaWEB开始。(Servlet为核心,从Servlet开始学习。) JSP(JSP使用较少了,但是还有用,

    2024年02月15日
    浏览(32)
  • 九、会话控制——cookie、session、token

    HTTP是一种无状态协议,它没有办法区分多次的请求是否来自于同一个客户端,无法区分用户。而产品中又大量存在这样的需求,所以我们需要通过会话控制来解决问题。 常见的会话控制有三种: (1)cookie (2)session (3)token cookie 是HTTP服务器发送到用户浏览器并保存在本

    2024年02月11日
    浏览(32)
  • web学习--Cookie与Session会话技术

    1.概念:客户端会话技术,将数据保存在客户端 使用步骤: 1,创建Cookie对象,绑定数据 2.发送Cookie对象 3.获取Cookie,拿到数据 WebServlet(\\\"/Demo1\\\") public class CookidDemo1 extends HttpServlet {     @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException

    2024年02月13日
    浏览(35)
  • gin会话控制篇 - Cookie和Session

    HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出 Cookie就是解决HTTP协议无状态的方案之一,中文是小甜饼的意思 Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求

    2024年01月21日
    浏览(29)
  • 会话跟踪技术学习笔记(Cookie+Session)+ HTTP学习笔记

    1.1 Cookie 1. Cookie:是一种客户端会话技术,数据会被保存在客户端,Cookie会携带数据访问服务器,用以完成一次会话内多次请求间的数据共享 2. 过程:浏览器(客户端)先向服务端发送请求,服务端会发送一个Cookie给客户端,在此后同一次会话中,每次客户端都会将Cookie发送

    2024年02月10日
    浏览(36)
  • 【python】flask基于cookie和session来实现会话控制

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开

    2024年03月24日
    浏览(36)
  • 如何在个人web项目中使用会话技术(cookie&session)?

    编译软件:IntelliJ IDEA 2019.2.4 x64 操作系统:win10 x64 位 家庭版 服务器软件:apache-tomcat-8.5.27 翻开百度百科关于“ 会话 ”的词条,它是这样描述:“ 在计算机术语中,会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一

    2023年04月22日
    浏览(46)
  • 如何让你的会话更安全,浅析Session与Cookie

            在我们面试的时候,面试官问及 XSS 漏洞的时候,我们常常会说比如劫持 Cookie,问及防御方法的时候,又常常会说设置 httponly ,本篇文章将从代码层面简单的普及 Session 和 Cookie 的生成过程,及防御的方法,希望看到这篇文章后,下一次遇到面试官的时候,你能够

    2024年02月22日
    浏览(43)
  • 使用Session和cookie会话对象实现简单购物车功能(超详细)

    1.新建Dynamic Web project,新建过程如下; 2.在src目录下新建两个包,一个命名为entity,一个命名为servlet,新建过程如下; 3.在entity目录下新建两个实体类,一个名为Cake,一个名为CakeDB,新建过程如下: 4.在servlet目录下新建三个servlet,命名分别为ListCakeServlet、PurchaseServlet和CartSe

    2023年04月17日
    浏览(63)
  • 【Servlet学习六】Cookie 与Session && 实现登录与上传文件

    目录 一、Cookie与Session(掌握) 🌈1、Cookie是什么? 🌈2、Session是什么? 二、代码功能演示 🌈1、实现登录功能(掌握) 🌈2、实现上传文件功能(掌握) 1、目标:实现程序,通过网页上传一张图片到服务器。 2、核心方法总结 问题1:为什么会有cookie?         HTTP协议

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包