自学内容网 自学内容网

Spring MVC 基础:接受请求参数

一、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 请求,你可以这样使用:

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

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

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

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

@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 中的参数,如:

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

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

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

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

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

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

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

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

@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 文件:

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

在 Spring MVC 中,直接使用字符串来接收参数后再手动处理确实是一种可行的方法,尤其是在某些情况下,你可能想对接收到的数据进行特殊处理,或者原始数据格式与你的业务逻辑需求不完全匹配时。这种方式提供了更大的灵活性,允许你在将数据转换成 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 对象,你可以将请求体作为一个普通的字符串接收:

@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 值。

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

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

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

解决方案
1.使用包装类

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

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

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

@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,并使用包装类来明确表明这个参数是可选的:

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


原文地址:https://blog.csdn.net/m0_74209411/article/details/142363041

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!