文章标题:
Spring MVC参数绑定深度剖析:各类参数与文件上传详尽阐释
文章内容:
我们通过浏览器访问不同的路径,其实就是在发送不同的请求,而发送请求时可能会携带一些参数,本文将会讲解Spring MVC中处理不同请求参数的多种方式。
一、传递单个参数
在Spring MVC中,接收单个参数可以直接通过方法中的参数来实现,例如下面的代码:
@RequestMapping("Param")
@RestController
public class ParamController {
@RequestMapping("a1")
public String tex1(String string){
return "接收到参数:"+string;
}
}
当我们使用Postman进行传参后,在浏览器访问[127.0.0.1:8080/Param/a1?string=Spring]
时,Spring MVC会根据方法找到对应的参数并赋值。需要注意的是,如果参数不一致,获取到的参数会是null(对于包装类型而言)。
注意事项:使用基本类型接收参数时,参数必须传递(boolean类型除外),否则会报500错误;若类型不匹配,则会报400错误(这些状态码会在其他篇章讲解)。
1.1、正常传递参数
@RequestMapping("a2")
public Object text2(int a){
return "接收到参数a:"+a;
}
通过Fiddler观察请求和响应,会发现HTTP响应状态码为200(表示正常)。
1.2、不传a参数
当不传a参数时,通过Fiddler观察请求和响应,会发现HTTP响应状态码为500(服务器异常)。此时观察程序错误日志,会提示类似“可选的整型参数‘a’存在,但由于被声明为基本类型,所以无法转换为null值。建议将其声明为对应基本类型的对象包装器”的信息。
1.3、传递参数类型不匹配
对于包装类型,如果不传对应参数,Spring接收到的数据会是null。所以在开发中,对于可能为空的参数,建议使用包装类型。
二、传递多个参数
传递多个参数时,和传递单个参数一样,直接使用方法的参数接收即可。例如:
@RestController
public class ParamController {
@RequestMapping("Param")
public String Demo1(String name,String age){
return "接收到参数name: "+name+" ,age: "+age;
}
}
使用浏览器发送请求并传参[127.0.0.1:8080/Param?name=小奥奇&age=8]
,可以看到后端程序能正确获取到name和age参数的值。需要注意的是,前后端是以参数名称进行匹配的,参数的位置不影响后端获取参数的结果。
三、传递对象
当需要传递较多参数时,使用方法传参会比较麻烦,这时可以将参数封装成一个对象。Spring MVC能够自动实现对象参数的赋值。首先创建一个Cat对象:
public class Cat {
private String name;
private int age;
private String hobby;
// 省略getter和setter方法以及toString方法
}
实现传递对象的方法:
@RequestMapping("Cat")
public Object Cat(Cat cat){
return cat.toString();
}
使用浏览器发送请求并传参[127.0.0.1:8080/Cat?name=咪咪&age=1&hobby=喜欢吃小鱼干]
,可以看到Spring会根据参数名称自动绑定到对象的各个属性上。如果属性未传递,基本类型会被赋值为默认初始值(如int类型赋值为0),引用类型则赋值为null。
四、后端参数重命名(后端参数映射)
在某些情况下,前端传递的参数key和后端接收的key不一致,这时可以使用@RequestParam
注解来重命名前后端的参数值。例如:
@RequestMapping("A1")
public String A1(@RequestParam("p") String password){
return "接收参数: password:"+password;
}
该注解表示从前端接收名为p的值并赋值给password。需要注意的是,当使用@RequestParam
注解时,默认该参数是必传的,若要设置为非必传参数,可以通过required = false
来设置,如:
@RequestMapping("A1")
public String A1(@RequestParam(value = "p",required = false) String password){
return "接收参数: password:"+password;
}
结论:使用@RequestParam
进行参数重命名时,请求参数必须与@RequestParam
声明的名称一致才能进行参数绑定和赋值,且默认该参数为必传参数。
五、传递数组
传递数组时,可以直接将数组作为参数,例如:
@RequestMapping("A2")
public String A2(String[] arr){
return "接收参数:arr:"+ Arrays.toString(arr);
}
传递数组包含多个元素时,可以通过特定方式传递,例如在一行中用逗号分隔多个元素,但如果元素本身包含逗号,则需要进行转义(如转为%2c)。
六、传递集合
传递集合参数时,需要使用@RequestParam
绑定参数关系,Spring会自动将多个同名参数的值收集到一个集合中。例如:
@RequestMapping("A1")
public String A1(@RequestParam List<Integer> list){
return "接收参数:"+list;
}
七、传递JSON数据
7.1、JSON概念
JSON全称为JavaScript Object Notation,是一种轻量级的数据交互格式,本质上是字符串,用于不同语言间的数据传递和交换。
7.2、JSON语法
JSON有特定的格式和语法,例如简单的JSON对象格式为{"key":"value",...}
,复杂对象可能包含嵌套的对象和数组等结构。可以使用在线JSON格式化工具(如https://www.bejson.com/)进行校验和书写。
7.3、JSON的优点
- 简单易用:语法简洁,易于理解和编写。
- 跨平台支持:可被多种编程语言解析和生成。
- 轻量级:相较于XML,传输时占用带宽小,传输速度快。
- 易于扩展:支持嵌套对象和数组等复杂结构。
- 安全性:纯文本格式,不包含可执行代码,安全性较高。
7.4、JSON字符串和Java对象互转
Spring MVC集成了JSON转换工具,可通过ObjectMapper
对象的writeValueAsString
方法将对象转为JSON字符串,通过readValue
方法将JSON字符串转为对象。例如:
public class JSONText {
@Test
public void JsontoJava() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String s="{\"name\":\"咪咪\",\"age\":1,\"color\":\"blue\"}";
Animals cat=mapper.readValue(s,Animals.class);
System.out.println(cat.toString());
}
@Test
public void JavatoJson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Animals cat = new Animals();
cat.setName("cat");
cat.setAge(1);
cat.setColor("blue");
String str = mapper.writeValueAsString(cat);
System.out.println(str);
}
}
7.5、传递JSON对象
接收JSON对象需要使用@RequestBody
注解,该注解作用在请求正文的数据绑定上,请求参数必须写在请求正文中。例如:
@RequestMapping("A3")
public String A3(@RequestBody Animals animals){
System.out.println(animals.getColor());
animals.color="彩虹色";
return animals.toString();
}
八、获取URL中参数@PathVariable
@PathVariable
注解用于请求URL路径上的数据绑定。例如:
@RequestMapping("A4/{id}")
public String A4(@PathVariable Integer id){
return "获取id: "+id;
}
还可以传递多个参数:
@RequestMapping("A4/{id}/{age}")
public String A4(@PathVariable Integer id,@PathVariable Integer age) {
return "获取id: "+id+",age: "+age;
}
默认情况下,@PathVariable
注解的参数是必传的,若设置为非必传可能会导致Spring无法正确识别参数,所以一般建议作为必传参数使用。
九、上传文件@RequestPart
上传文件时可以使用@RequestPart
注解,例如:
@RequestMapping("A5")
public String A5(MultipartFile file) {
System.out.println(file.getOriginalFilename());
return "文件获取成功";
}