锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. 解析 Cookies 与 Session 及其在 Spring MVC 中的操作与应用

解析 Cookies 与 Session 及其在 Spring MVC 中的操作与应用

0
  • 软件开发
  • 发布于 2024-09-20
  • 0 次阅读
黄健
黄健
  1. Cookies 和 Session 的概念

Cookies 和 Session 是 Web 应用中用于 跟踪用户状态 和 保持用户会话 的两种常见机制,它们各自有不同的使用场景和工作原理。

1.1 Cookies

Cookies 是由服务器发送给客户端的小块数据,存储在客户端的浏览器中。每次客户端请求服务器时,都会将存储的 Cookies 发送回服务器,从而实现数据的持久化和状态的保存。

  • 特性:

  • 客户端存储 :Cookies 是由浏览器存储在客户端的,它是 键值对形式 的数据。

  • 持久性:Cookies 可以设置过期时间,使其在用户关闭浏览器后依然有效。

  • 隐私问题:由于 Cookies 存储在客户端,容易被恶意修改或窃取,所以不适合存储敏感信息(如密码、银行卡号等)。

  • 常见用途:

  • 用户登录状态的保持(如记住用户的偏好设置)。

  • 跟踪用户的浏览历史。

  • 实现购物车功能。

1.2 Session

Session 是存储在 服务器端 的数据结构,用于保存用户与服务器之间的会话信息。客户端通常使用 Cookies 存储 Session ID,并在每次请求中将其发送给服务器,以便服务器能够找到与该 Session ID 相关的会话信息。

  • 特性:

  • 服务器端存储:Session 数据保存在服务器上,客户端仅持有 Session ID。

  • 生命周期:Session 的生命周期通常与用户的会话相关联,在用户关闭浏览器或超时后,Session 会自动销毁。

  • 安全性:由于数据存储在服务器端,相对于 Cookies 更为安全,尤其适合存储敏感信息(如用户凭证)。

  • 常见用途:

  • 用户登录会话管理。

  • 保存用户的临时数据,如购物车、订单信息等。

  • Cookies 和 Session 的区别

| 特性 | Cookies | Session |
|———-|——————-|——————————|
| 存储位置 | 客户端(浏览器) | 服务器端 |
| 数据大小 | 通常较小,限制为4KB左右 | 可以存储较大数据,受服务器内存限制 |
| 安全性 | 较低,可能被客户端篡改或劫持 | 较高,敏感数据存储在服务器 |
| 存储方式 | 以键值对形式保存在浏览器 | 键值对形式存储在服务器,客户端只保留Session ID |
| 生命周期 | 可以设置过期时间 | 生命周期通常与会话(Session)持续时间一致 |
| 适用场景 | 保存用户偏好、跟踪历史、持久化数据 | 保存用户状态、会话管理(如登录状态) |

  1. 如何在 Spring MVC 中操作 Cookies

在 Spring MVC 中,你可以使用 HttpServletResponse 对象来创建和发送 Cookies,也可以通过 HttpServletRequest 获取客户端发送的 Cookies。

创建和设置 Cookies

要向客户端发送一个 Cookie,可以使用 HttpServletResponse 的 addCookie() 方法。

示例:向客户端发送 Cookie

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class CookieController {

    @GetMapping("/setCookie")
    public String setCookie(HttpServletResponse response) {
        // 创建一个 Cookie
        Cookie cookie = new Cookie("username", "Alice");

        // 设置 Cookie 的有效期为 7 天
        cookie.setMaxAge(7 * 24 * 60 * 60);

        // 将 Cookie 添加到响应中
        response.addCookie(cookie);

        return "cookieSet";
    }
}
  • new Cookie() :创建一个新的 Cookie,键为 "username",值为 "Alice"。
  • cookie.setMaxAge():设置 Cookie 的有效期(以秒为单位),这里设置为 7 天。
  • response.addCookie():将 Cookie 发送到客户端,浏览器将接收到并存储这个 Cookie。

读取 Cookies

要从客户端获取 Cookie,可以使用 HttpServletRequest 的 getCookies() 方法,它会返回客户端发送的所有 Cookies。

示例:从客户端读取 Cookie

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class CookieController {

    @GetMapping("/getCookie")
    public String getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();  // 获取所有 Cookie

        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("username".equals(cookie.getName())) {
                    System.out.println("Username: " + cookie.getValue());
                }
            }
        }
        return "cookieGet";
    }
}
  • request.getCookies():获取客户端发送的所有 Cookies。

  • 遍历 Cookies:可以遍历 Cookies 数组,找到我们需要的 Cookie,并获取它的值。

  • 如何在 Spring MVC 中操作Session

在 Spring MVC 中,你可以通过 HttpSession 对象来操作服务器端的 Session。HttpSession 提供了存储和读取 Session 数据的功能。

4.1使用原生的Servlet API (HttpSession)

设置 Session 数据

通过 HttpSession 的 setAttribute() 方法,可以将业务数据保存到 Session 中。

示例:向 Session 中存储数据

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SessionController {

    @GetMapping("/setSession")
    public String setSession(HttpSession session) {
        session.setAttribute("user", "Alice");  // 将 "user" 数据存入 Session
        return "sessionSet";
    }
}
  • session.setAttribute() :将数据存储到 Session 中,键为 "user",值为 "Alice"。
读取 Session 数据

通过 HttpSession 的 getAttribute() 方法,可以从 Session 中获取数据。

示例:从 Session 中读取数据

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SessionController {

    @GetMapping("/getSession")
    public String getSession(HttpSession session) {
        String user = (String) session.getAttribute("user");  // 从 Session 中获取 "user"
        System.out.println("User: " + user);
        return "sessionGet";
    }
}
  • session.getAttribute() :从 Session 中获取存储的数据,使用键 "user"。
删除 Session 数据

你可以通过 HttpSession 的 removeAttribute() 方法删除特定的 Session 属性,或者使用 invalidate() 方法销毁整个 Session。

示例:删除 Session 数据

@GetMapping("/removeSession")
public String removeSession(HttpSession session) {
    session.removeAttribute("user");  // 删除 "user" 属性
    return "sessionRemoved";
}
  • session.removeAttribute():删除指定的 Session 属性。

示例:销毁整个 Session

@GetMapping("/invalidateSession")
public String invalidateSession(HttpSession session) {
    session.invalidate();  // 销毁当前 Session
    return "sessionInvalidated";
}
  • session.invalidate():销毁整个会话,所有的 Session 数据都会被清除。

4.2 使用@SessionAttribute注解实现Session数据获取

@SessionAttribute 是 Spring MVC 提供的注解,用于从 当前Session 中直接提取数据。它可以简化从Session中获取数据的操作,而不需要显式地通过 HttpSession 获取。@SessionAttribute 常用于从Session中获取已存在的数据。

功能实现

通过 @SessionAttribute 注解,你可以在方法参数中直接声明要从Session中提取的属性名称,并将其注入到控制器方法中。这使得代码更简洁,特别是当你只需要读取Session中的数据时。

示例代码:使用 @SessionAttribute 实现功能

1. 从Session中获取数据

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.SessionAttribute;

@Controller
public class SessionAttributeController {

    // 使用 @SessionAttribute 从Session中直接获取数据
    @GetMapping("/getSessionUser")
    public String getSessionUser(@SessionAttribute("user") String user) {
        System.out.println("User from session: " + user);  // 输出用户信息
        return "userProfile";
    }
}
  • 解释 :
  • @SessionAttribute("user") :告诉Spring从Session中获取键为 "user" 的属性,并将其注入到 user 变量中。
  • 如果Session中不存在指定的属性,则会抛出异常,因此要确保该属性已存在于Session中。

4.3 原生HttpSession 与 @SessionAttribute的区别与选择

4.3.1 操作方式的区别

  • HttpSession:

  • 需要显式地通过 HttpSession 对象来存取或删除Session数据。

  • 提供了对Session生命周期的完整控制,如销毁Session或删除某些属性。

  • 更灵活,适合需要对Session进行多种操作的场景。

  • @SessionAttribute:

  • 主要用于从Session中 读取 数据,并将其直接注入到控制器方法中。

  • 简化了代码编写,不需要手动操作 HttpSession,但不适合存储和删除Session数据。

  • 适合场景是你只需要访问已存储在Session中的数据,尤其是只读访问。

4.3.2 应用场景

  • 使用HttpSession:

  • 存储、读取、删除 数据:当你需要对Session进行完整操作时,如设置属性、读取属性或销毁整个Session,HttpSession 是最好的选择。

  • 复杂会话管理 :如果你需要对Session数据进行更细粒度的控制(如添加或删除多个属性),或者需要管理Session的生命周期(如过期、销毁等),使用 HttpSession 是最灵活的。

  • 使用@SessionAttribute:

  • 读取现有Session数据 :当你只需要从Session中获取数据且不打算修改或删除数据时,@SessionAttribute 提供了一种更简洁的方式。

  • 读取只读数据 :比如,在多个控制器方法中需要使用用户的登录信息,但这些信息是只读的,使用 @SessionAttribute 直接从Session中注入数据更为方便。

4.3.3 组合使用

在实际开发中,可能会组合使用 HttpSession 和 @SessionAttribute 。你可以使用 HttpSession 来存储数据,然后通过 @SessionAttribute 简单高效地在其他控制器方法中访问这些数据。

示例:组合使用HttpSession 和 @SessionAttribute
1. 使用HttpSession 存储数据
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SessionStorageController {

    @GetMapping("/setSessionUser")
    public String setSessionUser(HttpSession session) {
        session.setAttribute("user", "Alice");  // 存储用户信息到Session
        return "sessionSet";
    }
}
2. 使用@SessionAttribute 读取数据
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.SessionAttribute;

@Controller
public class SessionAccessController {

    @GetMapping("/showSessionUser")
    public String showSessionUser(@SessionAttribute("user") String user) {
        System.out.println("User in session: " + user);  // 从Session读取用户信息
        return "userProfile";
    }
}

4.3.4. 总结

  • HttpSession:提供了对Session数据的完整控制,适用于存储、读取和删除Session中的属性,管理Session的生命周期。适合用于复杂会话管理和需要操作Session数据的场景。
  • @SessionAttribute:主要用于读取Session中已有的数据,简化了获取Session数据的过程。适用于只需要访问Session中现有数据的场景。

两者可以组合使用,开发者可以根据具体需求选择合适的方式管理Session数据。在需要复杂的Session管理时,HttpSession 提供了更多灵活性,而在只需要读取Session数据的场景中,@SessionAttribute 提供了简洁的方式。

  1. Spring MVC 中的 Session 和 Cookies 应用场景

  2. Cookies 应用场景:

  3. 适合存储不敏感且长期有效的用户偏好、登录状态(如"记住我"功能)。

  4. 可以用来实现广告跟踪、用户行为分析等。

  5. Session 应用场景:

  6. 适合存储敏感信息或需要在多个请求之间共享的数据,如用户登录状态、购物车数据等。

  7. Session 的数据保存在服务器上,具有更高的安全性,适用于存储复杂数据对象或用户相关的会话信息。

  8. Cookies 和 Session 的安全性考虑

  9. Cookies 安全性:

  10. HTTP-only :设置 HttpOnly 属性,防止 JavaScript 读取 Cookie,避免 XSS 攻击。

  11. Secure :设置 Secure 属性,确保 Cookies 只在 HTTPS 连接时传输,防止网络中窃取。

  12. 敏感数据存储:避免将敏感数据(如密码、Session ID)直接存储在 Cookies 中。

  13. Session 安全性:

  14. Session 固定攻击:确保在用户重新登录时生成新的 Session ID,防止会话劫持。

  15. Session 超时:设置合理的 Session 过期时间,避免长时间不活动的会话被利用。

  16. HTTPS:使用 HTTPS 来保护传输中的 Session ID,避免被窃取。

  17. 总结

  18. Cookies 用于客户端数据存储,适合较小、非敏感的数据。Spring MVC 中通过 HttpServletResponse 和 HttpServletRequest 操作 Cookies,常用于存储用户偏好和轻量级数据。

  19. Session 是服务器端的会话管理机制,用于存储需要在多个请求间保持的用户状态。通过 HttpSession 操作 Session,适合存储敏感且需要跨请求的数据。

  20. 二者结合使用时,通常是用 Cookies 保存 Session ID,Session 负责管理服务器端的用户状态,从而保证数据安全和跨请求的状态持久性。

原文链接: https://blog.csdn.net/m0_73837751/article/details/141902600

标签: #软件开发 1171 #SpringMVC 58
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.