Cookie 和 Session

简介: Cookie 和 Session

前言


虽然在默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系,但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的,例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了。而上面的操作则是通过 cookie 和 session 来完成的。

cookie 和 session的作用

在很多网站中,你每次进行一些操作的时候,都需要判断你是否是登录状态,如果没有登陆的话就不能进行一些操作。当用户登录成功之后,服务器会在服务器这里生成一个 sessionId: session 类似这样的键值对的结构,然后存储在服务器本地,并且在响应的时候将这个 sessionId 给携带上,当浏览器接收到这个请求并且拿到这个 session 的时候就会将这个 sessionId 存储在cookie 中。下次向服务器发送请求的时候就会将这个 cookie 和请求数据包一起发送给服务器,当服务器拿到这个 cookie 中的 sessionId 的时候就会根据这个 sessionId 找到对应的 session 从而完成一系列的操作。


给大家举个例子:当我们第一次去某个医院的时候,医院会给根据你提供的身份证为我们开一个就诊卡,这个身份证就相当于我们的用户名和密码,这个就诊卡就相当于 cookie,并且与之对应的,通过这个就诊卡医生可以查询到你的病史、余额等等这些信息,当你去其他的科室看病的时候,就不再需要我们提供身份证了,而是就诊卡;而医院这边呢就会通过你提供的就诊卡,也就是 cookie,来获取到你的个人信息,也就是 session,这样你就能查看到该病人的一些相关信息。



HttpServletRequest和HttpServletResponse中与cookie和session相关的方法

HttpServletRequest 类中的相关方法


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

HttpServletResponse 类中的相关方法

方法 描述
void addCookie(Cookie cookie) 把指定的 cookie 添加到响应中


每个 Cookie 对象就是一个键值对。


方法 描述
String getName() 该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 SetCooke 字段设置给浏览器的)
String getValue() 该方法获取与 cookie 关联的值
void setValue(String newValue) 该方法设置与 cookie 关联的值
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/cookie")
public class cookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf8");
        Cookie[] cookies = req.getCookies();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cookies.length; i++) {
            String name = cookies[i].getName();
            String value = cookies[i].getValue();
            sb.append(name + ": " + value + "<br>");
        }
        resp.getWriter().write(sb.toString());
    }
}

HttpSession

HttpSession 对象中也包含很多的键值对,我们可以获取或者添加一些键值对。


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


attribute 就是属性的意思。

这里我们先用 postman 发送一个 get 请求,让服务器添加一个 cookie,然后再用 postman 发送一个 post 请求查看我们的请求中是否有 cookie。

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
class Message {
    public String name;
    public String gender;
    public Message(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }
    @Override
    public String toString() {
        return "Message{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
@WebServlet("/test")
public class Test extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("name","zhangsan");
        resp.addCookie(cookie);
        resp.getWriter().write("ok");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf8");
        HttpSession httpSession = req.getSession(true);
        resp.getWriter().write(String.valueOf(httpSession.isNew()));
        Message message = new Message("zhangsan", "man");
        httpSession.setAttribute("cookie1", message);
        Message m = (Message)httpSession.getAttribute("cookie1");
        resp.getWriter().write(m.toString());
    }
}

这是post请求的数据包。


可以看到当我们发送 post 请求的时候,我们抓取到的请求数据包中是存在我们刚才get请求时创建的 cookie 的,不仅如此,cookie 中还有一个 jsession 这个键值对,这就是服务器在服务器本地生成的一对sessionId-session键值对之后返回给浏览器的sessionId,浏览器将这个 sessionId 给存储到了 cookie 中。

使用cookie和session实现一个简单的登录功能


当了解了cookie和session的基本使用,那么我们服务器就可以根据浏览器传来的cookie中的sessionId,得到对应的session对象,然后根据session对象中的相关属性来判断你这个账号的登录状态,如果你当前处于未登录的话,就提示你当前未登录,如果登录了的话,就显示出欢迎词。


使用form表单构造HTTP请求

我们这里的构造HTTP请求的界面很简单就是几个简单的输入框。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登录</title>
</head>
<body>
    <form action="login" method="post">
        <input type="text" name="username">
        <input type="text" name="password">
        <input type="submit" value="登录">
    </form>
</body>
</html>

判断输入的账户密码是否正确

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");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (!"zhangsan".equals(username) || "123".equals(password)) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("对不起,您输入的用户名或者密码不正确");
            return;
        }
        HttpSession httpSession = req.getSession(true);
        httpSession.setAttribute("username", username);
        httpSession.setAttribute("loginTime", System.currentTimeMillis());
        resp.sendRedirect("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("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession httpSession = req.getSession(false);
        resp.setContentType("text/html; charset=utf8");
        if (httpSession == null) {
            resp.getWriter().write("对不起,您当前未登录");
            return;
        }
        String username = (String)httpSession.getAttribute("username");
        Long loginTime = (Long)httpSession.getAttribute("loginTime");
        String responBody = "欢迎你" + username + "上次登录时间为" + loginTime;
        resp.getWriter().write(responBody);
    }
}

效果展示

相关文章
|
12天前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
36 4
|
15天前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
1月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
149 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
27天前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
19 1
|
2月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
2月前
|
存储 前端开发 Java
JavaWeb基础7——会话技术Cookie&Session
会话技术、Cookie的发送和获取、存活时间、Session钝化与活化、销毁、用户登录注册“记住我”和“验证码”案例
JavaWeb基础7——会话技术Cookie&Session
|
2月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
59 0
|
2月前
|
存储 JSON 数据安全/隐私保护
Cookie + Session 的时代已经过去了?
在探讨“Cookie + Session”这一经典组合是否已经过时的议题时,我们首先需要理解它们在Web应用认证和会话管理中的历史地位与当前面临的挑战。随着Web技术的飞速发展,特别是无状态服务、OAuth、JWT(JSON Web Tokens)等技术的兴起,这一传统机制确实面临了前所未有的变革压力。但说它“完全过去”或许过于绝对,因为它在特定场景下仍发挥着重要作用。
36 0
|
3月前
|
存储 JavaScript 前端开发
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
184 1
|
3月前
|
存储 安全 搜索推荐
【JavaWeb 秘籍】Cookie vs Session:揭秘 Web 会话管理的奥秘与实战指南!
【8月更文挑战第24天】本文以问答形式深入探讨了Web开发中关键的会话管理技术——Cookie与Session。首先解释了两者的基本概念及工作原理,随后对比分析了它们在存储位置、安全性及容量上的差异。接着,通过示例代码详细介绍了如何在JavaWeb环境中实现Cookie与Session的操作,包括创建与读取过程。最后,针对不同应用场景提供了选择使用Cookie或Session的指导建议,并提出了保障二者安全性的措施。阅读本文可帮助开发者更好地理解并应用这两种技术。
58 1