@GetMapping
public
Object
demo
(
@RequestParam
(
"hobby"
) String
[]
hobby) {
return
hobby;
Spring Boot 可以直接把以逗号分割的参数封装为集合、数组,例如:
$ curl "localhost:8080/demo?hobby=chang,tiao,rap"
["chang","tiao","rap"]
其他框架、程序不一定会根据逗号进行分割。更优雅的方式,也是通用的方式应该是多次声明同名参数,例如:
$ curl "localhost:8080/demo?hobby=chang&hobby=tiao&hobby=rap"
["chang","tiao","rap"]
数组也可以替换为
Collection
接口,Spring 都会正确地处理。特别是在一些需要对数组参数去重的场景,推荐使用
Set
作为参数,如下:
@GetMapping
public Object demo (@RequestParam("hobby") Set<String> hobby) {
return hobby;
发起请求,这一次
rap
值重复传递了 3 次:
$ "localhost:8080/demo?hobby=chang&hobby=tiao&hobby=rap&hobby=rap&hobby=rap"
["chang","tiao","rap"]
得益于
Set
自带去重的特性,所以最终
hobby
集合中重复的
rap
值,只保留了一个。
使用
Set
作为参数的时候,默认使用的实现是
java.util.LinkedHashSet
,目的是为了保证集合中的参数顺序和传递的顺序一样。
Spring 还会自动地把传递的字符串参数,转换为 Controller 方法声明的类型。
如,定义
Integer
类型的数组、集合:
@GetMapping
public Object demo (@RequestParam("val") Set<Integer> val) { // Set<Integer> 类型
return val;
发起请求,传递数值类型的字符串参数:
$ curl "localhost:8080/demo?val=1&val=2&val=3"
[1,2,3]
如果不能成功地转换,则会抛出异常。如下,最后一个参数传递了一个 NaN
字符串:
$ curl "localhost:8080/demo?val=1&val=2&val=NaN"
{"timestamp":"2023-09-22T09:07:48.592+00:00","status":400,"error":"Bad Request","path":"/demo"}
服务端异常消息如下:
Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String[]' to required type 'java.util.Set'; For input string: "NaN"]
甚至可以自动转换 LocalDate
类型:
@GetMapping
public Object demo (@RequestParam("times") Set<LocalDate> times) {
return times;
发起请求,传递日期格式的字符串参数:
curl "localhost:8080/demo?times=2023-09-22×=2023-09-23×=2023-09-24"
["2023-09-22","2023-09-23","2023-09-24"]
至于其他各种类型的参数,你都可以试一试!
对象中的普通数组
先定义一个简单的 User
对象,它有一个 String[]
类型的数组属性 :
public class User {
private Integer id;
private String name;
private String[] hobby; // 数组类型的参数
// 忽略 get、set 方法
修改 Controller,接收一个 User
类型的参数:
注意: 请求方式改为了 @PostMapping
,并且移除了 @RequestParam
注解。
@PostMapping
public Object demo (User user) {
return user;
为了更加直观的感受,这次使用 Postman 发起请求,对于数组类型的 hobby
参数,我们使用了逗号分割多个值:
也可以通过中括号 []
, 多次声明 hobby[]
来传递数组参数:
甚至可以在中括号中指定参数在数组中的索引,也就是下标。如下,我们把 rap
值放在了最前面,把 chang
值放在了最后面:
对象中的对象数组
修改 User
对象,它的 hobby
属性不再是一个普通的字符串数组。而是一个 Hobby
对象数组。
Hobby
对象以内部类形式定义,它有 2 个属性,如下:
public class User {
public static class Hobby {
private String id;
private String title;
private Integer id;
private String name;
private Hobby[] hobby; // Hobby 类型的数组属性
Controller 不需要改变。
由于数组参数 hobby
的元素类型是一个对象,对象有多个属性,因此需要在参数中指定其属性名称和值:
Java 枚举、JPA 和 PostgreSQL 枚举
在 Spring 中使用 Logbook 记录 HTTP 请求和响应
Spring Data JPA 检索最大值(Max Value)
在 Golang 中实现类似于 Spring 中的模板事务
Spring Boot v3.3.1 发布