Java ee Cookie和Session


提示:以下是本篇文章正文内容,下面案例可供参考

一、回顾Cookie

HTTP 协议自身是属于 “无状态” 协议.
ps:“无状态” 的含义指的是: 默认情况下 HTTP 协议的客户端和服务器之间的这次通信,
和下次通信之间没有直接的联系.

但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的
ps:例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了.
在这里插入图片描述
图中的 “令牌” 通常就存储在 Cookie 字段中
ps:回忆之前的例子:

  1. 到了医院先挂号. 挂号时候需要提供身份证, 同时得到了一张 “就诊卡”, 这个就诊卡就相当于
    患者的 “令牌”.
  2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别
    出当前患者的身份.
  3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁
    了. (类似于网站的注销操作)
  4. 又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”

二、理解会话机制(Session)

服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在
服务器这边记录每个用户令牌以及用户的信息的对应关系.
ps:在上面的例子中, 就诊卡就是一张 “令牌”. 要想让这个令牌能够生效, 就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系.

会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就
是用户信息(用户信息可以根据需求灵活设计)
ps:sessionId 是由服务器生成的一个 “唯一性字符串”, 从 session 机制的角度来看, 这个唯一性字符串
称为 “sessionId”. 但是站在整个登录流程中看待, 也可以把这个唯一性字符串称为 “token”.
sessionId 和 token 就可以理解成是同一个东西的不同叫法(不同视角的叫法).
在这里插入图片描述

当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId / token 返回给客户端.
(例如通过 HTTP 响应中的 Set-Cookie 字段返回).

客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId/ token.
(例如通过 HTTP 请求中的 Cookie 字段带上).

服务器收到请求之后, 根据请求中的 sessionId / token 在 Session 信息中获取到对应的用户信息,
再进行后续操作.

ps:Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.

三、Cookie 和 Session 的区别

在这里插入图片描述
在这里插入图片描述

四、核心方法

4.1HttpServletRequest 类中的相关方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.1.1HttpSession 类中的相关方法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.1.2Cookie 类中的相关方法

在这里插入图片描述
HTTP 的 Cooke 字段中存储的是多组键值对. 每个键值对在 Servlet 中都对应了一个 Cookie 对象.
通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.
通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.

在这里插入图片描述

4.2HttpServletResponse 类中的相关方法

在这里插入图片描述
在这里插入图片描述

五、代码示例: 实现简单用户登陆

基本逻辑如下图:
在这里插入图片描述

我们这里约定一下前后端交互接口
在这里插入图片描述
在这里插入图片描述
ps:针对前后端交互接口,有很多种约定方式,你确定其中一种即可

代码如下:

启动服务器

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 25397
 * Date: 2022-07-08
 * Time: 15:00
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理用户请求
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        //判断用户名或密码是否正确
        //一般来说这个判断操作需要放到数据库存取的
        //我们这里为了简单,就直接在代码里写死了,假设有效用户名和密码是“zhangsan”,“123”
        if("zhangsan".equals(username)&&"123".equals(password)){
            //为什么不写username.equals("zhangsan")?
            //一旦用户不输入用户名直接点登录,那就是null.equals,会出现空指针异常

            //登录成功
            //创建会话,并保存必要的身份信息
            //会话里可以保存任意指定的用户信息,比如我们这里可以实现一个简单的功能,记录用户访问主页的次数
            HttpSession httpSession= req.getSession(true);

            //往会话中存储键值对(必要信息)
            httpSession.setAttribute("username",username);

            //初始情况下,把登录次数count设为0
            httpSession.setAttribute("count",0);
            //setAttribute的第二个参数是Object,int不是Object但是Integer是
            //在上面的httpSession.setAttribute("count",0);代码中会触发Java中的自动装箱机制,自动把0转成Integer
            //我们存的是Integer,所以在后续的IndexServlet中也是用Integer来取

            resp.sendRedirect("index");//跳转到index页面
        }else{
            //登录失败
            resp.getWriter().write("login failed");
        }
    }
}

页面服务器

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 25397
 * Date: 2022-07-08
 * Time: 15:23
 */
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //返回一个主页(简单的html片段)
        //此处需要得到用户名(从HttpSession片段中可得)
        HttpSession session=req.getSession(false);
        //此处getSession的参数必须是false,前面在登录过程中,已经创建过会话了,此处是要直接获取之前的会话
        String username=(String) session.getAttribute("username");

        //除了用户名外,还从会话中取出count
        Integer count=(Integer)session.getAttribute("count");
        count+=1;
        //把自增后的值再写回到会话中
        session.setAttribute("count",count);

        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("<h3>欢迎你"+username+"这是第"+count+"次访问"+"<h3>");
    }
}

login.html

<!DOCTYPE html>
<html lang="en">
<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>

登录到页面,输入用户名密码
在这里插入图片描述

在这里插入图片描述
刷新一次
在这里插入图片描述
后续再刷新,访问次数逐次+1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

劲夫学编程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值