@RequestParam
@RequestParam,提交方式GET、POST。
- 可以从请求的地址中取出参数,也就是只能从 username=admin&password=admin这种字符串中解析出参数。@RequestParam可以处理get 或者post方式中
queryString
的值 - 也可以处理用来处理Content-type为“application/x-www-form-urlencoded”格式的请求,前端使用axios时候传递data 为
new URLSearchParams()
时候,请求Content-type自动转换
为“application/x-www-form-urlencoded”,参数在控制台里的Payload里显示为“Form Data”,用postman中在body中选择application/x-www-form-urlencoded”用来上传该格式请求 - 也可以用来处理Content-type为“multipart/form-data” 格式的请求, 前端使用axios时候传递data 为
new FormData()
时候,请求Content-type自动转换
为“multipart/form-data”,参数在控制台里的Payload里显示为“Form Data”,用postman中在body中选择“form-data”用来上传该格式请求(一般只用来文件上传)。java后台对于这种格式请求默认无法接收到除文件以外的任何参数的值 - get请求不能用@RequestParam接收对象参数(默认参数不加RequestParam修饰把对象参数的属性写在queryString,后台会自动映射到对象属性上,加了RequestParam修饰的参数,再使用queryString传递对象属性不会自动映射了)
application/x-www-form-urlencoded是浏览器默认的编码格式。对于Get请求,是将参数转换成?key=value&key=value格式,连接到url后
旧有的application/x-www-form-urlencoded:因为此类型不适合用于传输大型二进制数据或者包含非ASCII字符的数据。平常我们使用这个类型都是把表单数据使用url编码后传送给后端,二进制文件当然没办法一起编码进去了。所以multipart/form-data就诞生了,专门用于有效的传输文件
java RequestParam标记的参数必须匹配到,匹配不到会报错
使用@RequestParam接收前段参数比较方便,一般前端传参的URL:
url = “${ctx}/main/mm/am/edit?Id=${Id}&name=${name}”
后端使用集合来接受参数,灵活性较好,如果url中没有对参数赋key值,后端在接收时,会根据参数值的类型附,赋一个初始key(String、long ……)
@RequestMapping("/edit")
public String edit(Model model, @RequestParam Map<String, Object> paramMap ) {
long id = Long.parseLong(paramMap.get("id").toString());
String name = paramMap.get("name").toString;
return page("edit");
}
@PathVariable
使用@PathVariable接收参数,参数值需要在url进行占位,前端传参的URL:
前台实例:url = “${ctx}/main/mm/am/edit/${Id}/${name}”
服务端接受:
@RequestMapping("/edit/{id}/{name}")
public String edit(Model model, @PathVariable long id,@PathVariable String name) {
return page("edit");
}
前端传参的URL于后端@RequestMapping的URL必须相同且参数位置一一对应,否则前端会找不到后端地址
一、@RequestParam
先介绍一下@RequestParam的使用场景:
注解@RequestParam一般接收的参数是来自requestHeader中,即请求头。通常用于GET请求,比如常见的url:http://localhost:8081/spring-boot-study/novel/findByAuthorAndType?author=唐家三少&type=已完结
@RequestParam可以处理get 方式中
queryString
的值,也可以处理post方式中body中值为 formData类型(postman的post提交data为application/x-www-form-urlencoded格式)
的值。@RequestParam用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST。
@RequestParam有三个配置参数:
- required 表示是否必须,默认为 true,必须。
- defaultValue 可设置请求参数的默认值。
- value 为接收url的参数名(相当于key值)。
@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。
@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。比如向表中插入单条数据,但是这样不支持批量插入数据啊,如果改用 json 字符串来传值的话,类型设置为 application/json,点击发送的话,会报错,后台接收不到值,为 null。
这时候,注解@RequestBody就派上用场了。
二、@RequestBody
先介绍一下@RequestBody的使用场景:
注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded
编码格式的数据,比如:application/json、application/xml
等类型的数据。
就application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。即:可以把前段传过来的json数据封装到一个对象里,然后把这个对象作为参数传递给一个接口…
举个批量插入数据的例子,Controller层的写法如下图所示:
注意:前端使用$.ajax的话,一定要指定 contentType: “application/json;charset=utf-8;”,默认为 application/x-www-form-urlencoded。
请求中传JSON时设置的Content-Type 如果是application/json或者text/json时,JAVA中request.getParameter(“”)怎么也接收不到数据。这是因为,Tomcat的
HttpServletRequest
类的实现类为org.apache.catalina.connector.Request(实际上是org.apache.coyote.Request)。
- 当前端请求的Content-Type是Json时,可以用@RequestBody这个注解来解决。
- @RequestParam 底层是通过request.getParameter方式获得参数的,换句话说,@RequestParam 和request.getParameter是同一回事。+ 因为使用request.getParameter()方式获取参数,可以处理get 方式中queryString的值,也可以处理post方式中 body data的值。
- @RequestParam可以处理get 方式中queryString的值,也可以处理post方式中 body data的值。
- @RequestParam用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST。
@RequestBody接受的是一个json对象的字符串,而不是Json对象,在请求时往往都是Json对象,用JSON.stringify(data)的方式就能将对象变成json字符串。
总结:
前端请求传Json对象则后端使用@RequestParam;
前端请求传Json对象的字符串则后端使用@RequestBody。
前后端数据交互出现json数据类型不符合
此种情况为前端与后端json格式不统一导致
1.json 分为两种类型;
(1) json 对象类型,即前端定义的Content type 为 application/x-www-form-urlencoded等
(2) json字符串类型,即前端定义的Content type 为 application/json
var params1 = {
department_id: this.dataForm.deptId,
date_type: this.dataForm.dateType,
time: this.dataForm.dateTime
}
var params = JSON.stringify(params1)
console.log(params);
this.$http.post('/train/target/getReportDeptTarget', params,{ headers: { 'content-type': 'application/json ' }}).then(({ data: res }) => {})
@RequestPart
@RequestPart
这个注解用在multipart/form-data
表单提交请求的方法上。- 支持的请求方法的方式
MultipartFile
,属于Spring的MultipartResolver
类。这个请求是通过http协议
传输的
@RequestPart与@RequestParam区别
-
当请求方法的请求参数类型不是String 或 MultipartFile / Part时,而是复杂的请求域时,@RequestParam 依赖Converter or PropertyEditor进行数据解析, RequestPart参考 ‘Content-Type’ header,依赖HttpMessageConverters 进行数据解析
-
当请求为multipart/form-data时,@RequestParam只能接收String类型的name-value值,@RequestPart可以接收复杂的请求域(像json、xml);@RequestParam 依赖Converter or PropertyEditor进行数据解析, @RequestPart参考’Content-Type’ header,依赖HttpMessageConverters进行数据解析
前台请求:
jsonData
为Person
对象的json
字符串
uploadFile
为上传的图片
后台接收:
@RequestPart
可以将jsonData
的json数据
转换为Person对象
@RequestMapping("jsonDataAndUploadFile")
@ResponseBody
public String jsonDataAndUploadFile(@RequestPart("uploadFile") MultiPartFile uploadFile,
@RequestPart("jsonData") Person person) {
StringBuilder sb = new StringBuilder();
sb.append(uploadFile.getOriginalFilename()).append(";;;"));
return person.toString() + ":::" + sb.toString();
}
@RequestParam
对于jsonData
的json数据
只能用String字符串
来接收
@RequestMapping("jsonDataAndUploadFile")
@ResponseBody
public String jsonDataAndUploadFile(@RequestPart("uploadFile") MultiPartFile uploadFile,
@RequestParam("josnData") String jsonData) {
StringBuilder sb = new StringBuilder();
sb.append(uploadFile.getOriginalFilename()).append(";;;"));
return person.toString() + ":::" + sb.toString();
}
总结
当请求头中指定Content-Type:multipart/form-data时,传递的json参数,@RequestPart注解可以用对象来接收,@RequestParam只能用字符串接收