Spring MVC 基础:接受请求参数

news/2024/9/20 16:18:36 标签: spring, mvc, java, java-ee

一、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: 27

username=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.niftyadmin.cn/n/5667340.html

相关文章

如何查看Android设备的dpi

adb shell getprop ro.sf.lcd_density adb shell cat /system/build.prop > build_prop.txt shell cat system/build.prop 结果&#xff1a;参考&#xff1a; 如何查看Android设备的dpi_安卓 查看手机dpi-CSDN博客

ONNX Runtime学习之InferenceSession模块

ONNXRuntime库学习之InferenceSession(模块) 一、简介 onnxruntime.InferenceSession 是 ONNX Runtime 中用于加载和运行 ONNX 模型的核心模块。它提供了一种灵活的方式来在多种硬件设备&#xff08;如 CPU、GPU&#xff09;上执行 ONNX 模型推理。通过 InferenceSession&…

C语言 | Leetcode C语言题解之第416题分割等和子集

题目&#xff1a; 题解&#xff1a; bool canPartition(int* nums, int numsSize) {if (numsSize < 2) {return false;}int sum 0, maxNum 0;for (int i 0; i < numsSize; i) {sum nums[i];maxNum fmax(maxNum, nums[i]);}if (sum & 1) {return false;}int tar…

element-plus组件问题汇总

element-plus组件问题汇总 一、el-select 1. 下拉选项实现添加全部 问题描述&#xff1a;value为空时&#xff0c;select框中不显示全部选项&#xff0c;但是下拉列表中全部显示是勾选状态 图片&#xff1a; 解决办法&#xff1a;添加 :empty-values“[null, undefined]” …

第一次安装Pytorch

1、新版本的Anaconda内置的python版本是3.12&#xff0c; 目前 Windows 上的 PyTorch 仅支持 Python 3.8-3.11;不支持 Python 2.x。 1、创建运行环境 在不创建虚拟环境的情况下&#xff0c;不建议使用最新的Python和Anaconda。 在几次失败后&#xff0c;我使用的是Anaconda3-2…

深度学习常见面试题及答案(11~15)

算法学习、4对1辅导、论文辅导或核心期刊以及其他学习资源可以通过公众号滴滴我 文章目录 11. 解释一下神经网络中的反向传播算法的作用。一、计算误差二、误差反向传播三、参数更新 12. 简述深度学习中的过拟合问题及常见的解决方法。一、过拟合问题的表现二、过拟合问题的原因…

云原生信息安全:筑牢数字化时代的安全防线

云原生信息安全&#xff1a;筑牢数字化时代的安全防线 一、云原生信息安全概述 云原生安全包含两层重要含义。一方面&#xff0c;面向云原生环境的安全&#xff0c;目标是防护云原生环境中的基础设施、编排系统和微服务等系统的安全。在云原生内部&#xff0c;安全机制多以云原…

MySQL/Redis集群等数据库的管理、配置、优化、备份恢复、异地同步、数据迁移、安全防护的50道运维面试题

1. 请解释MySQL中的InnoDB和MyISAM存储引擎的区别。 在MySQL数据库中&#xff0c;InnoDB和MyISAM是两种常见的存储引擎&#xff0c;它们各自具有独特的特点和适用场景。以下是对这两种存储引擎的详细比较&#xff1a; 事务支持 InnoDB&#xff1a;支持事务处理&#xff0c;提…