一.Session介绍

session会话技术是基于cookie会话技术的,如图所示:

与cookie类似,当浏览器第一次发起请求时,服务器端会生成一个session对象,并设置session对象的id为1(举例说明),并将session对象存储在服务器端。然后将JESSIONID=1作为Set-Cookie响应给浏览器,浏览器接收到响应的Set-Cookie对象会自动将session对象存储在浏览器本地,然后在后续的每一次请求中都会将cookie的数据获取出来并携带到服务端,接下来服务器拿到cookie的值,也就是session的id,就会从当前众多session中找到对应的session。这样就可以通过session会话在同一次请求的多次响应之间共享数据。这就是根据session共享数据的流程。

二.代码

package com.gjw.controller;

import com.gjw.pojo.Result;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class SessionController {

    // cookie方式实现会话跟踪
    // 设置cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response) {
        response.addCookie(new Cookie("login_name","gjw"));
        return Result.success();
    }

    // 获取cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("login_name")) {
                System.out.println("login_name = " + cookie.getValue());
            }
        }
        return Result.success();
    }

    // session技术实现会话跟踪
    // 往HttpSession中存储值
    @GetMapping("/s1")
    public Result sesssion1(HttpSession session) {
        log.info("HttpSession-s1:{}",session.hashCode());

        session.setAttribute("loginUser","tom");
        return Result.success();
    }

    // 从HttpSession中获取值
    @GetMapping("/s2")
    public Result session2(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info("HttpSession-s2:{}",session.hashCode());

        Object loginUser = session.getAttribute("loginUser");
        log.info("loginUser: {}",loginUser);
        return Result.success(loginUser);
    }
}

通过session.setAttribute给session对象存值,通过session.getAttribute取出session的值。

运行localhost:8080/s1

服务器响应给浏览器前端的值为JESSIONID=JESSIONID的值。浏览器又将JESSIONID存储了起来。

 运行localhost:8080/s2

 发现Cookie中有携带浏览器存储的JESSIONID的数据。

三.Session,Cookie和JWT令牌的优劣比较

对于session来说,集群环境下是无法直接使用session的,因为我们当前的企业开发项目都是部署在多个服务器上的,以防止只有一台服务器挂掉后项目无法运行。那么用户如何确定要使用哪台服务器呢?这是由负载均衡服务器所决定的。但是如果使用cookie,那么只能在同一个服务器上访问,因为换一台服务器就找不到对应的cookie值了,这样的话数据就无法共享,那么使用cookie也就无法实现负载均衡,无法使用集群。

当前主流的方法是令牌技术,如JWT令牌,JWT令牌本质上是一串字符串,服务器端响应时可以将要存储的数据存储到JWT令牌中发送给浏览器端,浏览器端接收后存储起来。在浏览器发起请求时将JWT令牌携带到请求中发送给服务器端进行校验。从而实现登录和数据共享。

更多推荐