环境:Spring2.7.18
1. 简介
在Web开发中,请求参数处理是核心功能之一。SpringBoot提供了灵活且强大的参数绑定机制,能够自动将HTTP请求中的参数(如查询参数、路径变量、表单数据、JSON等)映射到控制器方法的参数上。无论是简单类型、复杂对象还是集合类型,SpringBoot都能通过注解(如@RequestParam、@PathVariable、@RequestBody等)实现无缝对接,极大地提升了开发效率与应用的健壮性。此外,它还支持数据校验、自定义参数解析器等高级特性,满足各种复杂的业务需求。对于表单数据,当设置Content-Type为multipart/form-data时,我们确实可以方便地实现文件的上传以及普通文本字段的提交。然而,在某些复杂场景中,我们可能希望除了上传文件外,还能将其他字段以非普通文本类型(如application/json、application/xml等)提交,这种场景又该如何实现呢?
对于application/json类型的数据,客户端通常会将请求的内容以JSON格式添加到HTTP请求的body中,并设置请求的Content-Type为application/json。在SpringBoot后端,当处理这种类型的数据时,我们只需在控制器方法的相应参数上使用@RequestBody注解,SpringBoot便会自动将请求体中的JSON数据转换成Java对象(如DTO、VO等)。
接下来我详细的介绍对于这种复杂的应用场景在SpringBoot中是如何进行处理的,这需要前后端配合。
2. 实战案例
既然要包含json对象,又要包含附近,所以这里我们需要结合@RequestPart注解,用该注解分别来指定要获取请求中哪部分内容,而Spring MVC底层会更加你的类型进行自动的转换。
2.1 基本操作
接口定义
@PostMapping("/requestpart")
public Object requestpart(
@RequestPart("user") User user,
@RequestPart("file") MultipartFile file
) throws Exception {
// TODO
file.transferTo(new File("f://m.png")) ;
return user ;
}
这里每个参数都通过@RequestPart来指定分别获取请求中的哪部分内容。接口定义完后,接下来看前端要如何处理
前端请求处理
前端我们需要借助FormData来添加每一项表单数据,同时还需要为每一项指明你的数据类型,如下示例:
let form = new FormData()
// 文件附件
form.append('file', document.querySelector('#file').files[0])
let data = {age: 5000, name: '中国🇨🇳'}
// 通过Blob来构建一个不可变、原始数据的类文件对象,同时指明你数据类型
let user = new Blob([JSON.stringify(data)], { type: 'application/json' })
form.append('user', user)
axios({
method: 'post',
url: 'http://localhost:8080/api/request/requestpart',
// 设置请求header,这里设置multipart/mixed也可以
headers: {
'Content-Type': 'multipart/form-data'
},
data: form
})
粗糙的前端页面
图片
后端接口成功的接收了json数据,再看看请求长什么样。
图片
通过请求Payload知道,每个请求部分都有自己的Content-Type。在后端接口会根据每个Content-Type进行数据类型的转换。
2.2 更多请求类型
你还可以指定更多的类型。
public Object requestpart(
@RequestPart("user") User user,
@RequestPart("xml") String xml,
@RequestPart("file") MultipartFile file)
前端通过通过Blob对象来指定数据类型。
let form = new FormData()
// other
// 制定类型为xml
let xml = new Blob(['<message><title>@RequestPart请求参数处理</title></message>'], {type: 'application/xml'})
form.append('xml', xml)
请求情况。
图片
如果你还有其它类型,可以任意的指定,只要后端有对应的参数解析器即可(后端如何转换类型会根据你请求的情况比如:根据Content-Type)。
2.3 参数校验
与@RequestBody请求参数一样,这里的@RequestPart也可以使用基于注解的方式进行参数的校验,如下示例:
@PostMapping("/requestpart")
public Object requestpart(
@Validated @RequestPart("user") User user,
BindingResult result,
@RequestPart(name = "xml", required = false) String xml,
@RequestPart("file") MultipartFile file
) throws Exception {
// TODO
if (result.hasErrors()) {
return result.toString() ;
}
return user ;
}
// User实体对象
public static class User {
private Integer age ;
@NotEmpty
private String name ;
// Getters, Setters
}
前端输出结果;
图片
注意:请求错误对象的位置,否则将在后端控制台抛出异常,当然如果你有全局异常处理也就无所谓了。