[JavaWeb开发中]Cookie 和 Session 的工作流程

1.用户信息

Http 是一个无状态协议。就是说这一次的请求和之前一次的请求是没有关联的,互不干涉。这种无状态的好处就是快速,坏处是需要进行用户状态保持得场景【登陆情况下跳转到其它页面或者多个页面之间共享信息】。不然用户跳转一次登陆一次,不仅对服务器资源消耗也会造成用户体验不佳。
因此 Cookie和Session 应运而生

2.Cookie

Http 是一个无状态的协议,但是访问有些资源的时候往往需要经过认证的账户才能访问, 而且要一直保持在线状态,所以,cookie是一种在浏览器端解决的方案,将登陆认证之后的用户信息保存在本地浏览器中,后面每次发起http请求,都自动携带上该信息,就能达到认证用户,保持用户在线的作用,具体如下图:
在这里插入图片描述

设置cookie的方法在 Http 的 Response 报头中可以携带 Set-Cookie 字段来完成
在这里插入图片描述
客户端记录Cookie信息,这个就是 Cookie 的工作机制

3.Session

把需要用到的信息保存在客户端虽然也可以,但是如果遇到一些敏感信息,这些信息都是和用户强相关的。保存在客户端这里就不太合适(不安全,资源多的话就占用带宽),因此存储在服务器里最合适。且服务器还可以进行一些加密操作【SHA1,MD5】
保存的方式就通过session(会话)方式存储的。
服务器这边会在用户登录成功之后,就生成一个键值对,key叫做sessionid;value就保存需要用的重要信息;然后客户端那边就需要保存这个sessionid即可,后续的请求也带上sessionid即可,然后服务器就根据sessionid来查找对应的信息。
在这里插入图片描述

会话的本质是一个哈希表这样的数据结构,存储了一些键值对这样的结构。key就是Cookie的的ID(token/SessionID),value就是Cookie信息(用户信息),这些信息可以灵活定义

这个 SessionID 是由服务器加密后生成的一个唯一性指定字符串。从 session 机制的角度来看,这个唯一性字符串称为SessionID ;但从整个登陆流程来看,也可以把这个唯一性字符串看为 token

在这里插入图片描述
好处:

  1. 客户端数据量很轻
  2. 客户端和服务器之间传输数据很少,节约带宽
  3. 数据都在务器存储,客户端数据损坏服务器还有备份。

Servlet 中的 Session 默认是存储在内存中的,因此重启 Tomcat 服务器时 Session 会刷新。

4.Cookie VS Session

两者有什么区别呢?

  • Cookie是客户端(浏览器)存储数据的一种机制,可以存储身份信息,也可以存储别的数据,都是程序猿自己定义的数据;而session存储在服务器数据的一种机制,也是键值对结构,主要就是用来存储身份相关的信息
  • 因为每次发起 Http 请求,都要携带有效Cookie信息,所以Cookie一般都有大小限制,以防止增加网络压力,一般不超过4k
  • 可以轻松访问cookie值但是我们无法轻松访问会话值,因此session方案更安全
  • SessionID/token 也不一定非要通过 Set-Cookie 字段进行传输
  • Cookie 和 Session 是配合使用但不是必须使用
  • 完全可以用 Cookie 来保存一些数据,但不应非要是身份信息,SessionID/token

5.Servlet中运用Cookie和Session案列

5.1 核心方法

在这里插入图片描述

5.1.1 HttpRequest

方法描述
HttpSession getSession(true/false)true:去查hahs表,存在就返回不存在就创建(先生成一个sessionid,再创建一个HttpSession对象。把这个键值对给插入到哈希表中,通过Set-Cookie把SessionID返回给客户端) false:查找到对应的sessionid就返回,没有查到就返回null
Cookie[] getCookies()在HttpRequest对象获取全部的cookie,一个请求中会有多个cookie键值对。每个键值对都是一个cookie对象

5.1.2 HttpResponse

方法描述
void addCookie(Cookie cooike)把指定的cookie添加到请求中

5.1.3 HttpSession

一个HttpSession中存储多个键值对对象,我们可以往里边存储任何我们需要的信息

方法描述
Object getAttribute(String name)返回session中指定名称的对象,如果没有则返回null
void setAttribute(String name, Object value)使用指定的名称绑定一个对象到session(会话)中
boolean isNew()判断当前会话是否是新建的

5.1.4 Cookie类

方法描述
String getName()返回cookie的名称,这个名称在创建后不可被修改【通过浏览器Set-Cookie字段返回】
String getValue()获取与cookie关联的值
void setValue(String newValue)修改与cookie关联的值
  • HTTP 中的 Cookie 字段实际存储的是多个键值对,

5.2 用户登录的一个示例

网页代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>
<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

登陆的servlet代码

package CookieAndSession;

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 {
        resp.setContentType("text/html;charset=UTF-8");
        // 1.从请求中获取到用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 2.对这里的参数进行校验
        if (username == null || password == null || "".equals(username) || "".equals(password)) {
            resp.getWriter().write("<h3>用户名或密码错误</h3>");
            return;
        }
        // 3.对用户名和密码进行校验
        if (!"admin".equals(username) || !"123".equals(password)) {
            resp.getWriter().write("<h3>用户名或密码错误</h3>");
            return;
        }
        // 4.登陆成功。创建一个会话,来记录当前的用户信息
        HttpSession session = req.getSession(true);
        // 5.给会话中保存一个自定义信息
        session.setAttribute("visitCount", 0);
        // 6.把登陆成功的页面返回给客户端(这里的反馈并不是简单的提示登陆成功,而是直接跳转到指定页面)
        resp.sendRedirect("index");
    }
}

显示登陆后的servlet代码

package CookieAndSession;

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 {
    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        HttpSession session = req.getSession(false);
        if (session == null) {
            resp.getWriter().write("<he>尚未登陆</h3>");
            return;
        }
        // 获取到了会话,用户是已经登陆过的。就从 session 里拿到之前定义好的 visitCount 访问次数
        Integer visitCount = (Integer) session.getAttribute("visitCount");
        ++visitCount;
        session.setAttribute("visitCount", visitCount);
        resp.getWriter().write("visitCount:" + visitCount);
    }
}

效果图展示在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
服务器重启后就会刷新
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值