【网络编程】Cookie和Session | 概念 | 核心方法 | 案例:实现用户登录

Cookie和Session

一、概念

Cookie: http请求header中的一个属性。

​ Cookie是浏览器持久化存储数据的一种机制。网页无法访问主机的文件系统,要想存储数据就需要通过Cookie来实现。Cookie中保存的数据,也是键值对的格式(用户自定义的)最终还是要把这些键值对发送回服务器。服务器要使用Cookie来完成一些业务逻辑。

  • 有些情况会使用Cookie存储当前用户的身份信息。(相当于就诊卡)

​ 每个用户都有产生一份这样的数据,这些数据会被存储在服务器的数据库中。在服务器代码的逻辑展开执行的过程中,这些数据就会从数据库查询出来,先临时的保存在某个内存结构当中,后续如果有修改之类的操作。就会修改内存,重新写入数据库。

这个内存结构,就称作“会话"(session)

Cookie:是客户端存储数据的机制

Session:是服务器临时存储数据的机制(不算持续化存储,持续化存储是数据库完成的)

两者会相互配合使用。

在Cookie中存储的用户身份标识,也经常会理解成sessionId

每个用户都有一个自己的Session,也有不同的sessionId.

服务器会存储很多的Session,因此拿着cookie中的sessionId,就可以找到用户对应的Session

​ 服务器会通过类似于hash表这样的键值对结构,来存储session。sessionId就是key,Session本身就是value。在Session里面存储用户自身的各种信息(同样的自定义的)。

在这里插入图片描述

  • 通过Cookie中的sessionid,来查询到对应的Session对象,从而得到用户的具体信息。

​ 可以通过Servlet的API来完成上述的操作。Cookie是浏览器的机制,Servlet提供了API来获取到Cookie。Session是服务器的机制,Servlet内部已经实现好了,也提供了API来方便进行使用。

二、核心方法

HttpServletRequest 类中的相关方法:

在这里插入图片描述

1.Cookie[ ] getCookies()方法
  • 返回一个Cookie对象的数组,拿到请求中所有cookie内容。每个cookie都是一个键值对,获取到所有键值对。
2.HttpSession getSession()方法
  • 这个方法能够完成:从cookie中获取sessionid,并且查询出对应session的过程。返回一个HttpSession对象

Servlet中通过HttpSession这个类来表示一个会话,服务器上有很多个会话。存在一个类似于HashMap< String,HttpSession>的结构。String是sessionid、HttpSession是Session对象。

  • 如果sessionid没有从Hash表上查到,这个方法也能自动创建一个键值对(分配新的sessionid,创建一个新的HttpSession对象)

  • 给登录场景来使用

        HttpSession session = req.getSession(true);
        //根据当前请求的cookie当中的sessionId来查询服务器的hash表,找到对应的Session对象。
        //当参数为true时,如果cookie中没有sessionId(首次登录时),或者sessionId没有找到对应的Session对象。就可以创建出一个session对象
  //把创建好的sessionId和Session对象存进hash表,并把sessionId设置到响应中(会在响应报头加上Set-Cookie字段),传回浏览器,让浏览器使用cookie保存

HttpServletResponse 类中的相关方法:

3.addCookie( Cookie cookie)
  • 服务器要想给浏览器返回一个Cookie,把Cookie添加到响应中

HttpSession类中的方法

  • 一个 HttpSession 对象里面包含多个键值对

在这里插入图片描述

4.getAttribute()和setAttribute()
  • set设置session对象中的键值对
        //通过Attribute,可以在会话中保存一些自定义的数据
        session.setAttribute("username",username);
        //Attribute也是键值对,存储的内容都是自定义的。这里的数据存储好后,后续跳转到其他页面,也随时可以把这个数据从会话中取出来实现一个数据在在多个Servlet之间共享。
        //Attribute是会话级别的,每个用户都有自己的数据,相互不会干扰

Cookie类中的方法

  • HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了一个 Cookie 对象.

  • 每个cookie对象就是一个键值对

在这里插入图片描述

三、实现用户登录

1.实现思路:

1.登录页面(html)

  • 发起一个get请求,来触发登录逻辑

2.通过Servlet处理登录的请求

  • 读取用户名和密码,并且验证是否登录成功
  • 如果登录成功,就会给当前用户创建一个会话,并且把得到sessionid,通过Cookie返回给客户端,客户端就会保存Cookie

3.网站主页

  • 通过另一个Servlet生成的动态页面。把用户数据显示在页面上。
2.登录页面:
预期发送的请求
POST login
Content-Type:application/x-www-form-urlencoded
//使用form表单,用这个格式
//如果使用json,就需要通过ajax来构造
 username=zhangsan&password=123
    //预计发送的数据格式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
</head>
<body>
<!-- 使用form表单来实现登录 -->
<form action="login" method="post">
    <input type="text" name="username">
    <input type="text" name="passward">
    <input type="submit" value="登录">
</form>
</body>
</html>
3.Servlet处理请求
 @WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.读取请求传来的参数(用户名和密码 )
        req.setCharacterEncoding("utf8");
        //先给请求设置一下字符集,否则如果username是中文,getParameter获取到的可能是乱码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //2.验证用户名和密码是否正确,
        if (!"张三".equals(username)||!"123".equals(password)){
            //这种写法,避免空值的情况。equals内部能够针对为null的参数做好处理。
            //登录失败,给用户返回提示
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前的用户名或者密码错误");
            return;
        }
        //3.登录成功后,给用户创建一个会话
        HttpSession session = req.getSession(true);
        //根据当前请求的cookie当中的sessionId来查询服务器的hash表,找到对应的Session对象。
        //当参数为true时,如果cookie中没有sessionId(首次登录时),或者sessionId没有找到对应的Session对象。就可以创建出一个session对象
        //把创建好的sessionId和Session对象存进hash表,并把sessionId设置到响应中(会在响应报头加上Set-Cookie字段),传回浏览器,让浏览器使用cookie保存

        //通过Attribute,可以在会话中保存一些自定义的数据
        session.setAttribute("username",username);
        //Attribute也是键值对,存储的内容都是自定义的。这里的数据存储好后,后续跳转到其他页面,也随时可以把这个数据从会话中取出来实现一个数据在在多个Servlet之间共享。
        //Attribute是会话级别的,每个用户都有自己的数据,相互不会干扰
        session.setAttribute("loginTime",System.currentTimeMillis());

        //4.此时登录成功后,让页面跳转到网站首页
        resp.sendRedirect("index");
        //重定向跳转到index页面上(后续写一个servlet生成这个页面)
    }
}

index页面

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取到当前用户对应的会话对象。生成的页面要根据当前的用户信息来构造。
        HttpSession session = req.getSession(false);
           //拿着之前响应返回给浏览器cookie的sessionId来查询Session对象
        if (session==null){
            //sessionId不存在,或者sessionId没有在hash表中查到
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前尚未登录");
            return;
        }
        //2.从会话中拿到之前存储的用户信息
        String username = (String) session.getAttribute("username");
        Long loginTime = (Long) session.getAttribute("loginTime");

        //3.生成一个页面,把上述数据显示到页面上
        resp.setContentType("text/html;charset=utf8");
        String respBody = "欢迎你 "+username+"!"+" 上次登录的时间是:"+loginTime;
        resp.getWriter().write(respBody);
    }
}

  • 浏览器首次访问登录操作的时候,就会在服务器这边验证身份。
  • 验证通过,就会创建会话
  • 服务器就会保存会话信息(按照Hash表)客户端保存身份标识(sessionId)。后续浏览器访问这个网站上的其他页面都会带上cookie(sessionId)。服务器不需要让浏览器重新登陆,也能识别出浏览器的用户身份信息。

点击移步博客主页,欢迎光临~

偷cyk的图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值