@RequestParam和@PathVirable和@RequestBody区别

@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标记的参数必须匹配到,匹配不到会报错

axios 发 post 请求,后端接收不到参数的解决方案

使用@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进行数据解析

前台请求:
jsonDataPerson对象的json字符串
uploadFile为上传的图片
在这里插入图片描述

后台接收:

  1. @RequestPart可以将jsonDatajson数据转换为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();
}
  1. @RequestParam对于jsonDatajson数据只能用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只能用字符串接收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值