Spring MVC:HTTP 请求的参数传递2.0

本篇博客接上文:

Spring MVC:Spring 前置知识 & HTTP 请求的参数传递1.0-CSDN博客

目录

1. 传递 json - @RequestBody

1.1 json

1.1.1 什么是 json

1.1.2 json 的语法

1.1.3 json 和 Java 中对象的转换

1.1.4 json 优点

1.2 传递 json

2. 获取路径参数 - @PathVariable

2.1 路径参数 / 请求参数

 2.2 如何获取

3. 接收/上传 文件

3.1 重命名 - @RequestPart

4. 获取 Cookie

4.1 HTTP - 无状态协议

4.2 cookie / session

4.2.1 sessionid

4.3 获取 Cookie

4.3.1 方法一: HttpServletRequest

4.3.2 方法二: @CookieValue 注解

5. 存储 session

5.1 getSession 方法

6. 获取 Session

6.1 方法一: HttpServletRequest

6.1.1 手动修改 Sessionid => 服务器查找 Session 失败

6.2 方法二: HttpSession

6.3 方法三: @SessionAttribute 

7. 获取 header

7.1 方法一: HttpServletRequest

7.2 方法二: @RequestHeader


1. 传递 json - @RequestBody

1.1 json

1.1.1 什么是 json

关于 json, 已经在前面的博客中介绍过了, 这进行一下简单回顾.

json, 是当下最流行一种数据组织的格式, 并且采用键值对的形式来存储数据. 键和值之间使用 :(冒号) 分割, 键值对和键值对之间使用 ,(逗号) 分割.

json 在保证可读性高的同时, 也尽可能的削减了冗余信息, 降低了网络带宽的消耗.

1.1.2 json 的语法

json 本质是一个字符串, 只不过对字符串的格式进行了约定. 其次, json 的语法格式类似于编程中对象的表示:

语法如下:

  1. 数据存储在键值对(Key/ Value)中
  2. 键和值之间使用 , 分割
  3. 键值对和键值对间使用 : 分割
  4. 对象使用 {} 表示
  5. 数组使用 [] 表示
  6. 每个键的值可以为数组, 也可以为对象, 数组中也可以包含多个对象

1.1.3 json 和 Java 中对象的转换

常见的 json 和 Java 对象的转换工具如下:

  1. gson(谷歌)
  2. fastjson(阿里)
  3. jackson

以上三个流行的第三方库, 均能完成 JSON 数据格式与 Java 对象之间的转化.
(注意, 以上三种方式均是由第三方提供的 Java 库, 使用时需引入依赖)

由于 Spring boot 项目本身自动引入了 Jackson 的依赖, 所以这里使用 Jackson 进行演示.
(spring-boot-starter-web 依赖会自动传递性地包含 jackson-databind 和其他相关的 Jackson 模块,因此在 Spring MVC 中我们不需要手动添加 Jackson 的依赖)

在 Jackson 中, 需要使用 ObjectMapper 类中的两个方法, 实现 json 和对象之间的转换:

  1. writeValueAsString => Java 对象转 json 字符串
  2. readValue => json 字符串转 Java 对象(需要注意, Java 对象接收时, 底层会调用对象的无参构造方法, 所以一定要提供无参构造) 

本次我们在 Test 单元测试包下进行代码的演示:

在测试包中, 可以对方法使用 @Test 注解, 使用注解后, 被注解的方法就是一个独立的进程(程序入口), 可以单独的运行(并且可以同时运行多个含 @Test 注解的方法):

public class JsonTest {

    @Test
    /**
     * 对象转 json
     */
    public void object2Json() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        UserInfo userInfo = new UserInfo();
        // 构建 Java 对象
        UserInfo userInfo1 = new UserInfo("dings", "123", 23);
        // 对象转 json
        String s1 =objectMapper.writeValueAsString(userInfo);
        System.out.println(s1);
    }
    @Test
    /**
     * json 转对象
     */
    public void json2Object() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        // 构建 json 字符串
        String s1 = "{\"userName\":\"dings\",\"password\":\"123\",\"age\":23}";
        // 注意, 这里使用 UserInfo 对象接收, 需要提供 UserInfo 的无参构造
        UserInfo userInfo = objectMapper.readValue(s1, UserInfo.class);
        System.out.println(userInfo.toString());
    }

}

1.1.4 json 优点

  1. 简单易用, 语法简单.

  2. 支持跨平台使用.

  3. 在保留 xml 可读性高的基础上, 语法更加轻量, 传输时消耗的带宽少

  4. 易于扩展, 结构灵活

  5. 纯文本格式, 安全性高

1.2 传递 json

若后端接收的是 json 数据, 那么形参需要使用 @RequestBody 注解, 表示该参数与请求 Body 中的数据进行绑定. (json 数据一定是在 body 中进行传输的)


2. 获取路径参数 - @PathVariable

2.1 路径参数 / 请求参数

路径参数: 

  • 路径参数是 URL 的一部分,主要用于标识资源.(不包含 IP 和 端口号)

请求参数:

  • 存在于 URL 的查询字符串中(? 后面的参数), 以及请求的 Body 中 

 2.2 如何获取

使用 @PathVariable 来将后端方法上的形参和路径参数进行绑定.

一个 @PathVariable 注解, 绑定一个路径参数, 若想获取多个路径, 需要多次绑定:

并且, 当要获取的路径参数和形参参数的名称不一致时, 可以对 @PathVariable 的 value 重新赋值, 进行重命名操作:

注意:

使用 @PathVariable 后, 对应在 URL 中路径参数必须存在!!(可以理解为必传项).


3. 接收/上传 文件

使用 MultipartFile 对象接收文件数据.

接收后, 调用 transferTo 方法可以对该文件进行上传操作:

3.1 重命名 - @RequestPart

当形参名称和前端传递的名称不一致时, 可以使用 @RequestPart 来进行参数绑定:


4. 获取 Cookie

4.1 HTTP - 无状态协议

为什么需要引入 Cookie 和 session 呢??

这是由于 HTTP 是一种 无状态 协议.

所谓 "无状态", 是指服务器在处理每个请求时不会保存任何关于之前请求的信息, HTTP 协议的 "无状态" 设计, 使得每个请求都是独立的.

简单来说,  "无状态", 就是指协议本身不会记录用户信息, 在协议眼中, 每一个用户都是相等的, 不会因为你访问过我, 我就记得你, 我对每一个用户都是公平公正的, 不会因为你访问的多, 我就偏爱你~~

虽然 无状态的设计是良好的, 但是在实际开发中, 很多情况下, 我们是需要保留和用户之间的交互信息的, 于是, 便引入了 Cookie.

4.2 cookie / session

在之前的博文中, 已经对 Cookie 和 session 进行了介绍, 这里再进行一下回顾.

Cookie 和 session 的主要区别是: Cookie 存储于客户端(用户的浏览器中), session 存储于服务器端.

Cookie 用来存储用户的偏好设置、会话标识符(如 sessionid )等信息,以便在用户再次访问网站时, 服务器能够识别用户(例如无需重复登录).

session 中, 保存了用户的详细信息, 存储于服务器中, 并且每一个用户, 都对应着一个唯一的 session 会话.

4.2.1 sessionid

sessionid 是 Cookie 中的一个属性. cookie 和 session 之间通过 sessionid 来进行关联.

最开始, sessionid 是由服务器生成的, 通过 Set-Cookie 发送给客户端. 此后, 客户端发送的请求中都会包含 Cookie(Cookie 中包含了 sessionid), 服务器收到请求后, 就会根据请求中的 sessionid 快速定位到与该用户对应的 session 会话.

  • sessionid 和 session 一一对应, 并且 sessionid 和 session 构成一组键值对, 存于内存的哈希表中.
  • 请求的 Cookie 中包含了 sessionid, 当请求到达服务器后, 服务器就会根据 sessionid(会话的唯一标识符), 查找到与之相对应的 session 会话(通过 key 查找 value).
  • sessionid本身不存储用户的相关信息. sessionid 是由服务器生成的唯一标识符,其主要作用是作为 session 的 "唯一标识",用于在服务器端标识和检索特定的用户会话.

4.3 获取 Cookie

进行了上文的铺垫, 可以来讲如何获取客户端中的 Cookie 了.

获取 Cookie 有以下两种方式:

  1. 通过 HttpServletRequest 对象来获取 [推荐]
  2. 通过 @CookieValue 注解来获取

在获取 Cookie 前, 我们先手动在客户端上设置 Cookie(服务器可以设置用户的 Cookie, 客户端也可以自己设置 Cookie):

在 postman 的客户端设置 Cookie:

  • 方法一:

  • 方法二:

在浏览器的客户端设置 Cookie:

4.3.1 方法一: HttpServletRequest

Http 请求中所有的内容(包括 URL, sessionID, header, ...) 都包含在 HttpServletRequest 对象中.

因此, HttpServletRequest 不仅能获取 Cookie, 还能获取请求中的其他信息:

其中的 getCookies 方法, 就可以获取 Cookie 的所有信息, 返回一个 Cookie[] 类型的数组:

使用 getKey 和 getValue 方法就可以读出 Cookie 中的 key-value 值.

4.3.2 方法二: @CookieValue 注解

除了使用 HttpServletRequest 获取 Cookie 外, 还可以使用 @CookieValue 注解 来获取 Cookie.

使用 @CookieValue 注解来获取 Cookie, 是一个简单的方式, 但是一次只能获取一个 Cookie 值.

若想获取多个 Cookie, 则需要多次使用 @CookieValue 注解.

// 方法1 获取 Cookie(推荐)
    @RequestMapping("/r12")
    public String r12(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for(Cookie cookie : cookies) {
                // Cookie => 键值对形式
                System.out.println(cookie.getName() + ":" + cookie.getValue());
            }
        }
        return "返回 Cookie 成功!!";
    }

    // 方法2 获取 Cookie
    @RequestMapping("/r13")
    public String r13(@CookieValue("name") String name,
                      @CookieValue("age") int age) {
        return "从 Cookie 中获取的 name: " + name +"; age: " + age;
    }

5. 存储 session

站在后端代码角度, 要给用户设置 Session, 必须要先拿到 Session 对象, 再对 Session 对象完成赋值操作.

Spring 中, 可以通过 getSession 方法获取 Session 对象.

5.1 getSession 方法

要获取 Session 对象, 首先需要获取 sessionid, 再根据 Sessionid 在服务器中寻找的 Session.

而 Sessionid 存储在客户端的请求中. 因此, 获取 Session 对象, 仍然需要使用 HttpServletRequest 来获取.(HttpServletRequest 可以获取请求中的所有信息, 包括 Sessionid[见上文])

因此, getSession 是 HttpServletRequest 类中的方法.

获取到 Session 对象后(首次获取的 Session 对象肯定是空的), 就可以使用 setAttribute 来填充对象(填写用户的信息).

注意: Session 是存储在内存中的. 当程序启动时, Spring 会给 Session 申请一定的内存空间来保存用户信息, 也就是说, 如果 Spring 进程进行了重启, 那么它之前存储的 Session 信息就会消失.

其实, getSession 方法有两种形式, 一个上图使用的不带参数的版本; 还有一个是带参数的版本, 可以传入 true / false. 而上图使用的不带参数的版本, 默认传的参数是 true.

getSession() == getSession(true).

那么传 true 或者传 false 有什么区别??

getSession 方法, 本质上就是 Spring 通过请求中的 sessionid 来获取 session 的. 而请求中 sessionid 对应的 Session 可能是存在的, 也可能是不存在的.

  • 当 Session 存在时: 不管传 true 还是 false, getSession 返回的都是保存了用户信息的 Session 对象.
  • 当 Session 不存在时: 若 getSession 参数为 false ==> 返回 null; 若 getSession 参数为 true ==> 返回空的 Session 对象.

所以, 存储 Session,时 应使用参数为 true 的版本来获取是 Session 对象, 不管 Sessionid 存不存在, 都可以保存用户信息:

  1. 当 Sessionid 不存在时, 则创建一个新对象, 后续使用 setAttribute 来初始化
  2. 当 Sessionid 存在时, 则获取该 Session, 后续使用 setAttribute 进行替换
// 存储 session ==> session 存储在服务端
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request) {
        // 从请求的 Cookie 中获取 sessionID
        // 再根据 sessionID 在服务器端获取 session

        // HttpSession session = request.getSession(true); // 不存在, 返回空的 Session 对象
        // HttpSession session2 = request.getSession(false); // 不存在, 返回 null
        HttpSession session = request.getSession(); // 不存在, 返回空的 Session 对象(默认为 true)
        // 在 Session 中存用户信息
        // 存储在内存中
        session.setAttribute("userName", "丁帅彪");
        session.setAttribute("age", "19");

        return "session 设置并存储成功!!";
    }

6. 获取 Session

上文, 我们只是将用户的信息保存在了服务器的 Session 中, 我们是看不见的.

但是, 我们也可以通过程序来获取 Session 中的信息.

6.1 方法一: HttpServletRequest

方法一,

仍然是通过 HttpServletRequest 中的 getSession 获取 Session 对象.

如果获取成功, 就可以通过 getAttruibute 方法获取 Session 中的信息

 

6.1.1 手动修改 Sessionid => 服务器查找 Session 失败

之前提到, Session 保存在服务器上, Sessionid 保存在客户端的 Cookie 的上, 我们可以在各个客户端中查看他们的 Sessionid 值(postman 和 浏览器属于两个不同的用户, 不同的客户端, 具有不同的 Sessionid):

如果我们手动将客户端保存的 Sessionid 修改成错误的, 那么后续用户发起请求时, 服务器查找 Session 就会查找失败:

6.2 方法二: HttpSession

方法二是方法一的简化, 可以使用 HttpSession 直接接收 session 对象.
(相当于 request.getSession() / request.getSession(true))

6.3 方法三: @SessionAttribute 

方法三是方法二的进一步简化, 使用 @SessionAttribute 注解, 直接获得 session 中的信息.
(相当于 session.getAttribute("key 值"))

以上三个获取 Session 的方法, 可以说是一步步进行了简化:


7. 获取 header

获取 header 也有两个方式:

  1. 通过 HttpServletRequest 获取
  2. 通过 @RequestHeader 获取

7.1 方法一: HttpServletRequest

header 也是请求中的内容, 因此, 也可以通过 HttpServletRequest 中的 getHeader 方法来获取.

因为 header 中也是采用的 键值对 的形式来存储信息的, 因此, getHeader 也是输入 key 值, 获取对应的 value 值.

一般来说, 一个 http 请求的 header 中, 都会有 User-Agent. 因此, 我们通过代码来获取请求中的 User-Agent:

7.2 方法二: @RequestHeader

方法二, 就是通过注解来获取 header 中的信息.

通过注解获取来 header, 就相当与 request.getHeader("key 值")

    // 方法1 获取 header
    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return "获取 header 中的 User-Agent: " + userAgent;
    }

    // 方法2 获取 header
    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
        return "获取 header 中的 User-Agent: " + userAgent;
    }

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/958580.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子应用设计方案103:智能家庭AI浴缸系统设计

智能家庭 AI 浴缸系统设计 一、引言 智能家庭 AI 浴缸系统旨在为用户提供更加舒适、便捷和个性化的沐浴体验,融合了人工智能技术和先进的水疗功能。 二、系统概述 1. 系统目标 - 实现水温、水位和水流的精确控制。 - 提供多种按摩模式和水疗功能。 - 具备智能清洁…

设计模式的艺术-外观模式

结构性模式的名称、定义、学习难度和使用频率如下表所示: 1.如何理解外观模式 外观类充当了软件系统中的“服务员”,它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。 外观模式(Facade Pattern)&a…

“““【运用 R 语言里的“predict”函数针对 Cox 模型展开新数据的预测以及推理。】“““

主题与背景 本文主要介绍了如何在R语言中使用predict函数对已拟合的Cox比例风险模型进行新数据的预测和推理。Cox模型是一种常用的生存分析方法,用于评估多个因素对事件发生时间的影响。文章通过具体的代码示例展示了如何使用predict函数的不同参数来获取生存概率和…

戴尔电脑设置u盘启动_戴尔电脑设置u盘启动多种方法

最近有很多网友问,戴尔台式机怎么设置u盘启动,特别是近两年的戴尔台式机比较复杂,有些网友不知道怎么设置,其实设置u盘启动有两种方法,下面小编教大家戴尔电脑设置u盘启动方法。 戴尔电脑设置u盘启动方法一、戴尔进入b…

【React】 react路由

这一篇文章的重点在于将React关于路由的问题都给搞清楚。 一个路由就是一个映射关系,key:value。key是路径,value 可能是function或者component。 安装react-router-dom包使用路由服务,我这里想要用的是6版本的包,因此后面加”6&q…

隐私保护+性能优化,RyTuneX 让你的电脑更快更安全

RyTuneX 是一款专为 Windows 10 和 11 用户量身打造的系统优化工具,采用先进的 WinUI 3 框架开发,以其现代化的设计风格和强大的功能集合脱颖而出。这款工具不仅界面简洁美观,还提供了多样化的系统优化选项,旨在帮助用户最大化设备…

HTML新春烟花

系列文章 序号目录1HTML满屏跳动的爱心(可写字)2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心(简易版)7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心(双心版)1…

(回溯分割)leetcode93 复原IP地址

#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; //卡尔的图不是按照程序执行过程而是直接画程序会执行的过程 // 实际执行是&#xff1a;n个字符&#xff0c;递推n1后&#xff08;叶子节点&#xff…

关于ARM和汇编语言

一图流 ARM 计算机组成 输入设备 输出设备 存储设备 运算器 控制器 处理器读取内存程序执行的过程 取指阶段&#xff1a;控制器器通过地址总线向存储器发送想要获取的指令的地址编号&#xff0c;存储器将指定的指令发送给处理器 译码阶段&#xff1a;控制器对指令进行分…

个人学习 - 什么是Vim?

观我往旧&#xff0c;同我仰春 - 2025.1.10 声明 仅作为个人学习使用&#xff0c;仅供参考 本文所有解释参考笔者个人理解&#xff0c;最终目的是服务于自我学习&#xff0c; 如果你需要了解官方更规范的解释&#xff0c;请自行查阅 Vim 是什么 Vim 是一个强大的 文本编辑器…

python学习笔记2-简单数据类型

不同类型的变量可以进⾏的运算是不同的&#xff0c;所以必须理解变量的类型&#xff0c;python中数据类型可以分为&#xff1a; Number&#xff08;数值&#xff09; 整型&#xff08;int&#xff09; python3中只有int⼀种&#xff0c;可以表⽰整数&#xff0c;例如&#xf…

ChromeOS 132 版本更新

ChromeOS 132 版本更新 1. 企业定制化 Chrome Web Store 管理员现在可以使用新设置定制 Chrome Web Store 以适应他们管理的用户&#xff0c;包括以下功能&#xff1a; 添加公司标志添加首页横幅和自定义公告策划扩展集合实施基于类别的控制 这些设置可以通过管理员控制台进…

Python的进程和线程

ref 接受几个设定: 进程是一家almost密不透风的公司,缅甸KK园区 线程里面工作的…人 进程**[园区]**内公共资源对于进程来说,可以共享. 别的园区[进程],一般不能和自己的园区共享人员资源,除非… 好的,现在再接受设定: 单个CPU在任一时刻只能执行单个线程&#xff0c;只有…

03垃圾回收篇(D4_彻底理解GC)

目录 一、浅析大促备战过程中出现的 fullGc&#xff0c;我们能做什么&#xff1f; 1. 什么是 JVM 的 GC? 2. 写代码的时候能做什么&#xff1f; 3. 测试能做啥 4. 知识小结 二、MinorGC、MajorGC、FullGC垃圾回收介绍 1. MinorGC &#xff08;新生代垃圾回收&#xff09…

软件测试 —— jmeter(2)

软件测试 —— jmeter&#xff08;2&#xff09; HTTP默认请求头&#xff08;元件&#xff09;元件作用域和取样器作用域HTTP Cookie管理器同步定时器jmeter插件梯度压测线程组&#xff08;Stepping Thread Group&#xff09;参数解析总结 Response Times over TimeActive Thre…

分子动力学模拟里的术语:leap-frog蛙跳算法和‌Velocity-Verlet算法

分子动力学模拟&#xff08;Molecular Dynamics Simulation&#xff0c;简称MD&#xff09;是一种基于经典力学原理的计算物理方法&#xff0c;用于模拟原子和分子在给定时间内的运动和相互作用‌。以下是关于分子动力学模拟的一些核心术语和概念&#xff1a; ‌定义系统‌&am…

在 Windows 11 中为 SMB 3.x 文件共享协议提供 RDMA 支持

注&#xff1a;机翻&#xff0c;未校。 Enable SMB Direct in Windows 11 在 Windows 11 中启用 SMB Direct Provides RDMA support for the SMB 3.x file sharing protocol 为 SMB 3.x 文件共享协议提供 RDMA 支持 Vigneshwaran Vijayakumar November 3, 2024 Last Updat…

zabbix6.0安装及常用监控配置

文章目录 部署zabbix-serverzabbix监控节点部署解决zabbix中文乱码创建主机组创建模版配置主机与模版关联 监控boot分区监控网卡流量出网卡流量监控进入和出的总流量监控内存监控服务器端口用户自定应监控key值 (监控mysql查询数量)zabbix触发器监控cpu监控入网卡流量 邮件告警…

如何将使用unsloth微调的模型部署到ollama?

目录 一、将模型保存为gguf格式 二、下载llama.cpp 三、生成 llama-quantize 可执行文件 四、使用llama-quantize 五、训练模型 六、将模型部署到ollama 一、将模型保存为gguf格式 在你的训练代码 trainer.train() 之后添加&#xff1a; model.save_pretrained_gguf(&q…

【Hadoop面试题2025】

文章目录 简单题故障及相应的处理方法中等难度高难度小文件小文件的产生小文件问题的影响小文件治理方案推荐方案 冷文件冷文件的产生冷文件问题的影响冷文件治理方案推荐方案 简单题 一、基础概念类 什么是Hadoop&#xff1f; 答案&#xff1a;Hadoop是一个开源的分布式计算框…