Spring MVC 基础:接受请求参数

embedded/2024/9/25 13:59:34/

一、HTTP 请求 如何携带参数

在HTTP请求中携带参数的方式取决于你使用的请求方法。常见的HTTP方法有GET和POST,参数传递的方式也有所不同:

1. GET 方法

GET方法通常用于请求服务器发送资源,参数直接附加在URL之后,通过?分隔URL和参数,多个参数之间用&连接。例如:

GET /search?query=网络安全&sort=latest HTTP/1.1
Host: www.example.com

这里,URL是/search,参数有两个:

  • query=网络安全
  • sort=latest

2. POST 方法

POST方法通常用于提交数据到服务器。与GET方法不同,POST方法通常将参数包含在请求体中,不显示在URL中(但是普通的参数也可以出现在URL中)。只有form 表单在post 请求中固定在 body、get 出现在url 中。这样可以发送更大的数据量,也更安全。参数可以以不同的格式发送,常见的有:

表单数据(application/x-www-form-urlencoded

数据以键值对形式发送,键值对之间用&分隔,键和值之间用=连接,类似于URL查询字符串。例如:

POST /submit HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27username=alice&password=1234
JSON数据(application/json

数据以JSON格式发送,适用于复杂结构的数据交换。例如:

POST /api/data HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 47{"username": "alice", "password": "1234"}

虽然GET和POST是最常见的,但HTTP协议还支持其他方法,如PUT、DELETE等,这些方法也可以携带参数,通常是在请求体中,格式可以是表单数据、JSON或其他MIME类型。

小技巧

  • 使用GET方法时,由于URL长度存在限制,不适合传输大量信息。
  • 使用POST方法时,可通过适当的Content-Type头部来控制数据的编码方式。

二、Spring MVC 接受参数

在 Spring MVC 中,处理来自客户端的参数有几种常用的方式。Spring MVC 提供了灵活的方式来接收来自 HTTP 请求的参数,并将其绑定到控制器方法的参数中。这些方法包括使用注解如 @RequestParam, @PathVariable, @RequestBody, 和 @ModelAttribute 等。下面是这些注解的基本使用方法:

1. 使用 @RequestParam

这个注解用于处理来自查询字符串或表单数据的参数。例如,对于一个 GET 请求,你可以这样使用:

java">@GetMapping("/search")
public String search(@RequestParam("query") String query) {// 使用 query 参数return "Result for: " + query;
}

如果你的参数名和方法的参数名相同,你还可以省略 @RequestParam 中的值:

java">@GetMapping("/search")
public String search(@RequestParam String query) {return "Result for: " + query;
}

 如果参数⽐较多时, ⽅法声明就需要有很多形参. 并且后续每次新增⼀个参数, 也需要修改⽅法声明. 我们不妨把这些参数封装为⼀个对象.

java">@Data
public class Person {private int id;private String name;private String password;
}@RequestMapping("/m3")
public Object method3(Person p){return p.toString();
}
2. 使用 @PathVariable

用于处理 REST 风格的 URL 中的参数,如:

java">@GetMapping("/users/{userId}")
public String getUser(@PathVariable("userId") Long userId) {// 使用 userId 参数return "User profile for ID: " + userId;
}

如果变量名和参数名相同,也可以省略:

java">@GetMapping("/users/{userId}")
public String getUser(@PathVariable Long userId) {return "User profile for ID: " + userId;
}
3. 使用 @RequestBody

这个注解用于处理 JSON 或 XML 等请求体数据。通常与 POST 或 PUT 请求一起使用:

java">@PostMapping("/users")
public String addUser(@RequestBody User user) {// 处理 user 对象return "Added user with ID: " + user.getId();
}
4. 使用 @ModelAttribute

用于绑定请求参数到一个模型对象,通常用于处理表单提交:

java">@PostMapping("/users/update")
public String updateUser(@ModelAttribute User user) {// 更新 user 对象return "Updated user with ID: " + user.getId();
}
5.传递数组和集合

Spring MVC 可以⾃动绑定数组参数的赋值

java">@RequestMapping("/m5")
public String method5(String[] arrayParam) {return Arrays.toString(arrayParam);
}

集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系 默认情况下,请求中参数名相同的多个值,是封装到数组. 如果要封装到集合,要使⽤ @RequestParam 绑定参数关系 

6.接受String 转成 Json

Jackson 是在 Spring 框架中常用的 JSON 处理库。要使用 Jackson 进行 JSON 与字符串的互转,首先需要在你的项目中添加 Jackson 的依赖。如果你使用 Maven,可以添加如下依赖到你的 pom.xml 文件:

java"><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.3</version>
</dependency>

在 Spring MVC 中,直接使用字符串来接收参数后再手动处理确实是一种可行的方法,尤其是在某些情况下,你可能想对接收到的数据进行特殊处理,或者原始数据格式与你的业务逻辑需求不完全匹配时。这种方式提供了更大的灵活性,允许你在将数据转换成 Java 对象之前,先进行验证、清洗或者格式化。

java">import com.fasterxml.jackson.databind.ObjectMapper;public class JsonUtil {public static String toJson(Object obj) throws Exception {ObjectMapper mapper = new ObjectMapper();return mapper.writeValueAsString(obj);}
}// 使用
Person person = new Person("Alice", 30);
String jsonString = JsonUtil.toJson(person);
System.out.println(jsonString);

例如,如果你希望接收一个 JSON 格式的请求体,但暂时不想将其自动绑定到一个 Java 对象,你可以将请求体作为一个普通的字符串接收:

java">@PostMapping("/api/data")
public ResponseEntity<String> processData(@RequestBody String rawData) {try {// 手动解析 JSON 字符串ObjectMapper mapper = new ObjectMapper();JsonNode rootNode = mapper.readTree(rawData);// 假设我们需要处理 name 字段String name = rootNode.path("name").asText();// 进行业务逻辑处理return ResponseEntity.ok("Received name: " + name);} catch (JsonProcessingException e) {return ResponseEntity.badRequest().body("Invalid JSON");}
}

三、常见问题 

在 Spring MVC 中,当你使用基本数据类型(如 int, double, boolean 等)作为方法参数时,确实可能遇到一些问题,尤其是涉及到参数可能不存在或可选的情况。这是因为基本数据类型不能接受 null 值,而包装类(如 Integer, Double, Boolean 等)可以接受 null 值。

假设你有一个使用基本数据类型参数的方法:

java">@GetMapping("/calculate")
public String calculate(@RequestParam("number") int number) {// 使用 number 参数return "Result: " + number * 2;
}

如果 HTTP 请求没有提供 number 参数,Spring MVC 将尝试将 null 转换为基本类型 int,这将失败并引发一个异常,因为基本类型不能接受 null 值。

解决方案
1.使用包装类

更改参数为相应的包装类可以解决这个问题,因为包装类可以接受 null 值:

java">@GetMapping("/calculate")
public String calculate(@RequestParam("number") Integer number) {if (number == null) {return "Number parameter is missing";}return "Result: " + number * 2;
}
2.设置默认值

另一个常用的解决方案是为 @RequestParam 设置一个默认值,这样如果请求中没有提供该参数,将使用默认值:

java">@GetMapping("/calculate")
public String calculate(@RequestParam(value = "number", defaultValue = "0") int number) {// 无需检查 null,因为已经有默认值return "Result: " + number * 2;
}

在这个例子中,如果没有提供 number 参数,number 将默认为 0

3.设置 required 为 false

你也可以将 @RequestParamrequired 属性设置为 false,并使用包装类来明确表明这个参数是可选的:

java">@GetMapping("/calculate")
public String calculate(@RequestParam(value = "number", required = false) Integer number) {if (number == null) {return "Number parameter is optional";}return "Result: " + number * 2;
}


http://www.ppmy.cn/embedded/116640.html

相关文章

Springboot使用ThreadPoolTaskScheduler轻量级多线程定时任务框架

简介&#xff1a; Spring注解定时任务使用不是很灵活&#xff0c;如果想要灵活的配置定时任务&#xff0c;可以使用xxl-job 或者 quartz等定时任务框架&#xff0c;但是过于繁琐&#xff0c;可能成本较大。所以可以使用ThreadPoolTaskScheduler来灵活处理定时任务 ThreadPoolT…

Python中字典常用方法

# 定义字典: # 定义一个空字典 my_dict {}# 定义一个包含不同类型键值对的字典 my_dict {name: John, age: 30, 1: a, 2: b, 3: c} print(my_dict) # 输出&#xff1a;{name: John, age: 30, 1: a, 2: b, 3: c}# 定义一个嵌套字典&#xff08;字典中包含字典&#xff09; my…

C语言指针简介篇

1. 指针的基本概念 什么是指针&#xff1a; 指针是一个变量&#xff0c;用于存储另一个变量的内存地址。通过指针&#xff0c;程序可以直接访问和操作存储在内存中的数据。 指针与变量的关系&#xff1a; 在C语言中&#xff0c;每个变量都有一个地址&#xff0c;可以使用&运…

【Linux网络 —— 网络基础概念】

Linux网络 —— 网络基础概念 计算机网络背景网络发展 初始协议协议分层协议分层的好处 OSI七层模型TCP/IP五层(或四层)模型 再识协议为什么要有TCP/IP协议&#xff1f;什么是TCP/IP协议&#xff1f;TCP/IP协议与操作系统的关系所以究竟什么是协议&#xff1f; 网络传输基本流程…

灵当CRM系统index.php存在SQL注入漏洞

文章目录 免责申明漏洞描述搜索语法漏洞复现nuclei修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 漏洞描述 灵当CRM系统是一款功能全面、易于使用的客户关系管理&#xff08;C…

基于pdf.js实现对pdf预览、批注功能、 保存下载pdf,适配H5,平板 踩坑记录

项目场景&#xff1a; 在APP端实现对pdf的批注,能够下载保存.能够获取批注信息同时能够重新渲染到pdf中.基于pdf.js-4.5.136版本源码实现。pc端能够正常预览下载pdf&#xff0c;构建打包后嵌入uniapp的webview遇到的问题记录 问题描述 将构建打包后的代码嵌入到uniapp中&…

WPF入门教学八 Canvas与WrapPanel的使用

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;Canvas和WrapPanel是两种常用的布局容器。Canvas允许你在其内部自由地定位子元素&#xff0c;而WrapPanel则会根据可用空间自动排列子元素。下面是一个简单的入门教学&#xff0c;介绍如何在WPF中使…

解决pandas DataFrame创建时的长度不一致问题之ValueError: All arrays must be of the same length

在使用pandas库创建DataFrame时&#xff0c;一个常见的错误是遇到 "ValueError: All arrays must be of the same length" 信息。这个错误的提示是我们在尝试构建DataFrame时&#xff0c;提供给构造函数 的各个数组&#xff08;或列表&#xff09;的长度不匹配。下…