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

目录

  • 1.用户信息
  • 2.Cookie
  • 3.Session
  • 4.Cookie VS Session
  • 5.Servlet中运用Cookie和Session案列
    • 5.1 核心方法
      • 5.1.1 HttpRequest
      • 5.1.2 HttpResponse
      • 5.1.3 HttpSession
      • 5.1.4 Cookie类
    • 5.2 用户登录的一个示例

1.用户信息

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

2.Cookie

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

设置cookie的方法在 Http 的 Response 报头中可以携带 Set-Cookie 字段来完成
[JavaWeb开发中]Cookie 和 Session 的工作流程_第2张图片
客户端记录Cookie信息,这个就是 Cookie 的工作机制

3.Session

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

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

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

[JavaWeb开发中]Cookie 和 Session 的工作流程_第4张图片
好处:

  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("

用户名或密码错误

"
); return; } // 3.对用户名和密码进行校验 if (!"admin".equals(username) || !"123".equals(password)) { resp.getWriter().write("

用户名或密码错误

"
); 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("尚未登陆");
            return;
        }
        // 获取到了会话,用户是已经登陆过的。就从 session 里拿到之前定义好的 visitCount 访问次数
        Integer visitCount = (Integer) session.getAttribute("visitCount");
        ++visitCount;
        session.setAttribute("visitCount", visitCount);
        resp.getWriter().write("visitCount:" + visitCount);
    }
}

效果图展示[JavaWeb开发中]Cookie 和 Session 的工作流程_第5张图片

[JavaWeb开发中]Cookie 和 Session 的工作流程_第6张图片
[JavaWeb开发中]Cookie 和 Session 的工作流程_第7张图片
服务器重启后就会刷新
[JavaWeb开发中]Cookie 和 Session 的工作流程_第8张图片

你可能感兴趣的:(计算机网络,http)