SpringMVC 参数绑定详解

x33g5p2x  于2022-05-16 转载在 Spring  
字(5.4k)|赞(0)|评价(0)|浏览(382)

概述

记得之前跟前端同事联调接口的时候,后端SpringMVC需要接收数组类型的参数,然后跟前端说需要传数组类型过来。后来前端童鞋传了数组,但是后端接收不成功,联调失败。那时候由于时间关系没有仔细研究这块,当时想了个办法就是前端传一个json字符串,后端换成接收json字符串然后转成需要的数组对象。这显然不是一种好的做法,框架帮我们做好的事我们没有用上,还平白多了两次数据的转换。所以今天花时间研究了下,将springMVC的数据绑定做个总结。

1. 简单类型参数

即几种java原生的基本数据类型已经其封装类以及String类型。比较简单,选一种布尔类型来讲解。
测试代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(@RequestParam(name = "test") Boolean test) {
  4. System.out.println(test);
  5. return "success";
  6. }

使用postman工具发送请求:

控制台输出:

  1. true1

这种的比较简单,没有太多可说的。**这里需要注意的是,参数如果没有加@RequestParam注解的话,传参需要默认参数的名称test作为传参参数的名称,而且没有加注解的话,前端在发送http请求的时候可以不传该参数,也不会报错。但是如果加了该注解,在没有设置注解的属性required = false的前提下,该参数必传,不然会报400错误。如果该注解中指定了name属性,name前端需要以name的值作为前端传参名称,如果没有指定name属性,在按参数名称test为前端传参名称。**大家可逐一验证。

2. 简单类型数组/list

分别为两种情况:

1) 直接使用数组作为方法的参数,可以用@RequestParam注解修饰,如果使用List,必须使用@RequestParam注解修饰

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(String[] tests) {
  4. System.out.println(tests[0] + " " + tests[1]);
  5. return "success";
  6. }

这种前端传参需要遵守一定格式。

  • form表单
    表单元素name的值必须一样
  1. name="tests" value="arony1"
  2. name="tests" value="arony2"12

postman发送请求:

控制台输出:

  1. arony1 arony21
  • ajax
    数组各个元素值需用“,”隔开。
  1. data:{"tests":"arony1,arony2"}1

值得注意的是,如果后端的springMVC方法参数用的是数组来接收的话,前端用ajax发送请求,那么只能用上面这一种格式传参,使用下面说的tests[0],tests[1]传参是不行的。
postman发送请求:

控制台输出:

  1. arony1 arony21

2)使用自定义类里面封装一个数组或者List,用自定义类实例作为方法参数,不能用@RequestParam注解修饰

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(Person person) {
  4. System.out.println(person.getTests()[0] + " " + person.getTests()[1]);
  5. return "success";
  6. }

Person:

  1. public class Person {
  2. private String[] tests;
  3. public String[] getTests() {
  4. return tests;
  5. }
  6. public void setTests(String[] tests) {
  7. this.tests = tests;
  8. }
  9. }
  • form表单

有两种形式进行传值

  1. name="tests" value="arony1"
  2. name="tests" value="arony2"12
  3. name="tests[0]" value="arony1"
  4. name="tests[1]" value="arony2"12

postman发送请求:

控制台输出:

  1. arony1 arony21
  • ajax

ajax也有两种方式传值:

  1. data:{"tests":"arony1,arony2"}1
  2. data:{"tests[0]":"arony1","tests[1]":"arony2"}1

效果跟表单完全一样。

3. 自定义类型

首先定义一个自定类型User,包含以下属性,生成get/set方法,toString方法:

  1. private Integer id;
  2. private String loginname;12

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(User user) {
  4. System.out.println(user);
  5. return "success";
  6. }

postman发送请求:

控制台输出:

  1. User{id=1, loginname='arony'}1

可以看到,跟User属性名一样的参数如果传了值,就可以被User对象所接受,没有传的为默认值。
我们尝试下,给参数user加上@RequestParam注解看看。使用postman发送请求,会发现返回400。所以我们要理解@RequestParam注解含义,它标示的是该方法参数接受的是一个http参数。因此,如果是用一个自定义对象作为参数的话,不要在之前加上@RequestParam,因为SpringMVC在解析http请求的参数user的时候,不能将接收到的参数转化成一个User对象。

4. 自定义类型数组/list

注意:这种情况只能使用一个自定义类来包装数组/list。
再定义一个参数类:

  1. public class Parameter {
  2. private Person[] person;
  3. public Person[] getPerson() {
  4. return person;
  5. }
  6. public void setPerson(Person[] person) {
  7. this.person = person;
  8. }
  9. }

Person:

  1. public class Person {
  2. private String tests;
  3. public String getTests() {
  4. return tests;
  5. }
  6. public void setTests(String tests) {
  7. this.tests = tests;
  8. }
  9. }

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(Parameter parameter) {
  4. System.out.println(parameter.getPerson()[0].getTests() + " " + parameter.getPerson()[1].getTests());
  5. return "success";
  6. }
  • form表单传参
  1. name="person[0].tests" value="arony1"
  2. name="person[1].tests" value="arony2"12
  • ajax传参
  1. data:{"person[0].tests":"arony1","person[1].tests":"arony2"}1

postman发送请求:

控制台输出:

  1. arony1 arony21

5. Map<String,基本类型>

与上面一样 这种情况只能使用一个自定义类来包装map。

Parameter:

  1. public class Parameter {
  2. private Map<String, String> map;
  3. public Map<String, String> getMap() {
  4. return map;
  5. }
  6. public void setMap(Map<String, String> map) {
  7. this.map = map;
  8. }
  9. }

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(Parameter parameter) {
  4. parameter.getMap().forEach((key, value) -> {
  5. System.out.println(key + " " + value);
  6. });
  7. return "success";
  8. }

前端传参格式:

  • form表单
  1. name="map[key1]" value="arony1"
  2. name="map[key2]" value="arony2"
  3. 或者
  4. name="map.key1" value="arony1"
  5. name="map.key2" value="arony2"12345
  • ajax
  1. data:{"map[key1]":"arony1","map[key2]":"arony2"}
  2. 或者
  3. data:{"map.key1":"arony1","map.key2":"arony2"}123

postman发送请求:

控制台输出:

  1. key1 arony1
  2. key2 arony212

6. Map<String, 自定义类>

跟5是很类似的。
Parameter:

  1. public class Parameter {
  2. private Map<String, Person> map;
  3. public Map<String, Person> getMap() {
  4. return map;
  5. }
  6. public void setMap(Map<String, Person> map) {
  7. this.map = map;
  8. }
  9. }

Person:

  1. public class Person {
  2. private String tests;
  3. public String getTests() {
  4. return tests;
  5. }
  6. public void setTests(String tests) {
  7. this.tests = tests;
  8. }
  9. }

接口代码:

  1. @RequestMapping(value = "test")
  2. @ResponseBody
  3. public Object testDataBind(Parameter parameter) {
  4. parameter.getMap().forEach((key, value) -> {
  5. System.out.println(key + " " + value.getTests());
  6. });
  7. return "success";
  8. }

前端传参格式:

  • form表单
  1. name="map[key1].tests" value="arony1"
  2. name="map[key2].test2" value="arony2"12

这里注意,name=”map.key1.tests” value=”arony1”这样传值是不行的。必须用方括号。

  • ajax
  1. data={"map[key1].tests":"arony1","map[key2].test2":"arony2"}1

这里也必须使用方括号。

使用postman发送请求:

控制台输出:

  1. key1 arony1
  2. key2 arony212

总结

以上的SpringMVC参数绑定可以总结为下图:

其中,Map<String, ①> 前端还可以使用“.”代替方括号。

相关文章