你们好,我是金金金。
前言
撰写本文是因为好奇,好奇为什么,拼接的字符串数据过去能直接变成数组,好奇为什么让传,拼接的字符串而不是直接传递数组数据,好奇…
探索
- 首先看
get
请求,get
请求参数一般都是携带在路径后面的,还有一种就是参数直接成为路径的一部分,无非就是这两种,用得较多的一般都是参数携带在路径后面的,下面也将在这种方式上演示
Get请求
-
-
code
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@GetMapping("/add")public R<String> addCustomMenu(String[] menus) {System.out.println(Arrays.toString(menus));return R.success("添加成功");} }
-
浏览器访问
-
控制台输出
可以看到没有任何问题,为什么传递字符串数据能直接用数组接收呢?
- 因为
Spring MVC
对数组类型有特殊的处理逻辑。它会自动尝试将同名的查询参数或逗号分隔的字符串转换为数组
-
-
较多的是这种方式,因为操作集合数据比操作数组要方便的多~
-
code
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@GetMapping("/add")public R<String> addCustomMenu(List<String> menus) {System.out.println(menus);return R.success("添加成功");} }
-
浏览器访问
-
控制台
很不幸,报错了:java.lang.IllegalStateException: No primary or single unique constructor found for interface java.util.List
出错的原因:
- 在
SpringMVC
中,当需要接收请求参数时,可以使用@RequestParam
注解来指定参数的名称。 - 对于数组类型的参数,
SpringMVC
会自动将请求中的参数值转换成数组并将其赋值给对应的形参,因此在数组类型的形参列表中不需要加@RequestParam
注解。 - 而对于集合类型的参数,
SpringMVC
无法自动将请求中的参数值转换为集合类型,需要使用@RequestParam
注解来指定参数的名称,只有你加了这个注解,才会自动将请求中的数组转换为集合类型,这样才能正确的将参数赋值给对应的形参。
-
既然已经知道了问题产生的原因,来调整一下代码:
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@GetMapping("/add")public R<String> addCustomMenu(@RequestParam("menus") List<String> menus) {System.out.println(menus);return R.success("添加成功");} }
-
浏览器请求
-
控制台输出
-
成功了,这次知道原因了吧~ 我们接着看
Post
类型 ~
Post请求
-
- code
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@PostMapping("/add")public R<String> addCustomMenu(String[] menus) {System.out.println(Arrays.toString(menus));return R.success("添加成功");} }
-
由于是
Post
请求,我们用PostMan
来发起测试 -
控制台输出
可以看到和
Get
请求差不多~ 并无啥不同的地方 请求方式不同罢了 -
-
code
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@PostMapping("/add")public R<String> addCustomMenu(@RequestParam("menus") List<String> menus) {System.out.println(menus);return R.success("添加成功");} }
-
由于是
Post
请求,我们用PostMan
来发起测试 -
控制台输出
可以看到和
Get
请求差不多~ 并无啥不同的地方 请求方式不同罢了
-
-
post
请求还可以接收请求体当中的数据,这种方式下的话是不会自动转换的,需要手动去处理的,所以这种方式建议直接让前端传递数组就行-
code
@RestController @RequiredArgsConstructor @Slf4j @RequestMapping("/user/menu") public class CustomMenuController {@PostMapping("/add")public R<String> addCustomMenu(@RequestBody CustomMenuAddDTO customMenuAddDTO) {System.out.println(customMenuAddDTO);return R.success("添加成功");} }
@Data public class CustomMenuAddDTO implements Serializable {/*** 菜单名称集合*/private List<String> menus; }
-
由于是
Post
请求,我们用PostMan
来发起测试 -
控制台输出
请求体方式下,如果前端传递的是
menus: "1,2,3"
,在CustomMenuAddDTO
里面定义成String[]
或者List<String>
都是不行的。均会报错!除非类型改成private String menus
;那还得手动解析成数组,多麻烦,是不~ -
结尾
本篇文章均为个人所写,结论都是验证过的,请放心食用~ 哪里写的不对的,或者是哪里写的不好的,请大佬指出,感谢!
- 编写有误还请大佬指正,万分感谢。