@RequestBody、@RequestParam 、@PathVariable、@RequestPart

一、@RequestParam(一个方法中能使用多次)

1. 简介

  1. 用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,也就是常用的Query参数拼接(?service=110&name=spring)。

    (Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型)

  2. RequestParam可以接受简单类型的属性,也可以接受对象类型。 实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。

  3. 在Content-Type: application/x-www-form-urlencoded的请求中, get 方式中queryString的值,和post方式中 body data的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。

2. 实例

    @RequestMapping("uploadStringFile")
    public JsonResult uploadStringFile(@RequestParam("stringFile")String stringFile, 					   									@RequestParam("bucket") String bucket){
 
    }

二、 @RequestBody(一个方法中能使用多次,但是建议只使用一次)

1. 简介

  1. 处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。可以处理application/json或者是application/xml等,一般情况下来说常用其来处理application/json类型
  2. GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。
  3. POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。
  4. @RequestBody注解一次性将请求体中的数据全部取出来,所以不建议在一次方法中使用多次

2.实例

$.ajax({
        url:"/login",
        type:"POST",
        data:'{"userName":"admin","pwd","admin123"}',
        content-type:"application/json charset=utf-8",
        success:function(data){
          alert("request success ! ");
        }
    });
   @requestMapping("/login")
  public void login(@requestBody String userName,@requestBody String pwd){
      
  }

这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个User类,拥有如下字段:

	class User{
		String userName;
		String pwd; 
	}

那么上述参数可以改为以下形式:@RequestBody User user,这种形式会将JSON字符串中的值赋予user中对应的属性上,需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的

三、@PathVariable (一个方法中可以使用多次)

1. 简介

需要配合rest风格url使用,目的是接收rest Url中的参数,可以拼接多个
例如:
GET请求路径:http://127.0.0.1:8080/hello/4/zs

	@RequestMapping(value = "/hello/{pageSize}/{name}", method = RequestMethod.GET)
	public String say(@PathVariable("pageSize") String pageSize,@PathVariable("name") String name) {
       
    }

四、@RequestPart(复杂的请求场景)

1.简介

  1. @RequestPart这个注解用在multipart/form-data表单提交请求的方法上。
  2. 支持的请求方法的方式MultipartFile,属于Spring的MultipartResolver类。这个请求是通过http协议传输的。
  3. @RequestParam也同样支持multipart/form-data请求。(即两者都能用于后端接收文件)
  4. 他们最大的不同是,当请求方法的请求参数类型不再是String类型的时候,@RequestParam适用于name-valueString类型的请求域,@RequestPart适用于复杂的请求域(像JSON,XML)。

2.实例

	public Object taskSaveAttachment(@RequestPart("file") MultipartFile file,
   						@RequestPart("attachmentSaveVO")  @Valid AttachmentSaveVO attachmentSaveVO){
       
    }
	@RequestMapping("uploadFile")
	public JsonResult uploadFile(@RequestPart("file") MultipartFile file, @RequestParam String bucket){
 
    }
@RequestPart-同时上传文件和json的解决方案

1)通过@RequestParam("josnData") String jsonData 和@RequestPart("uploadFile") MultiPartFile uploadFile 两个注解分别接受参数,此时使用@RequestParam(“josnData”)注解接受的类型只能为String,需要自行进行JSON解析String,不过能实现POST上传文件类型参数和json格式字符串参数。

@RequestMapping("uploadFile")
	public JsonResult uploadFile(@RequestPart("uploadFile") MultipartFile[] uploadFiles, @RequestParam("jsonData") String jsonData){
 
    }

2)下面这种则使用@RequestPart注解接受JSON数据,此时可以将接收的json字符串直接序列化为实例对象,注意:此时json字符串一定要声明类型 Content-Type: application/json,否则使用@RequestPart注解无法反序列化

@RequestMapping("jsonDataAndUploadFile")
@ResponseBody
public String jsonDataAndUploadFile(@RequestPart("uploadFile") List<MultipartFile> uploadFiles,
                           @RequestPart("jsonData") Person person) {

}

在这里插入图片描述

org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver#resolveArgument
    HttpInputMessage inputMessage = new RequestPartServletServerHttpRequest(servletRequest, name);
    上面两行会根据参数名称以及请求实例化请求流。
     
        org.springframework.web.multipart.support.RequestPartServletServerHttpRequest#RequestPartServletServerHttpRequest
            HttpHeaders headers = this.multipartRequest.getMultipartHeaders(this.partName);
            在RequestPartServletServerHttpRequest初始化时候,会获取请求参数的请求头信息,如果头为空则会报异常操作
            如果存在则会正常解析内容。
多文件
	@PostMapping("/save")
	public void save(@RequestPart(required = false) FormData formData,
               @RequestParam(value="files", required=false) MultipartFile[] files) {
   
}

这里的files多文件在postman上是这样调用的:
在这里插入图片描述

五、总结

1. 小结

  1. 在GET请求中,不能使用@RequestBody。

  2. 在POST请求中,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,对于参数转化的配置必须统一。
    举个例子,在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。

  3. 如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。

  4. 另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。

  5. 综上所述,一般情况下,推荐使用@RequestParam注解来接受Http请求参数。

  6. Get请求不能使用表单(没有请求体),只能在url中传参,传参方式只有这一种。 Post请求可以使用表单,也可以在url中传参。
    使用表单时有几种数据类型(表现为数据的存储位置不同):
    1、 x-www-form-urlencoded 参数存储在query中 用@RequestParam接收。
    2、formdata 参数存储在body中,用@RequestBody接收,文件类型用@RequestPart接收。
    3、raw(json,xml) 参数存储在body中 用@RequetBody接收。
    总结一下: 凡是放在body中的都可以用@RequestBody接收,文件类型的数据可以用@RequestPart接收。 凡是放在query中的都可以用@RequestParam接收,包括Get方式提交和Post(x-www-form-urlencoded)方式提交的。

2. 分类

注解GETPOST支持的Content-Type不支持的Content-Type
@RequestBodyapplication/json,application/xmlapplication/x-www-form-urlencoded
@RequestParammultipart/form-data,application/x-www-form-urlencoded
@RequestPartmultipart/form-data,application/x-www-form-urlencoded,application/json,application/xml
@PathVariable

六、 实际使用情况

  1. 如果项目组规定使用 rest 风格的api 并且参数不是很复杂不是很多的得情况下优先使用 @PathVariable 注解接收路径穿过来的参数
  2. 能使用@PathVariable 注解的地方都能使用 @RequestParam 进行替换 ,@RequestParam 注解既能接收get请求 问号传参过来的参数,也能接收post请求 问号传参,(post也能使用问号传参)以及post请求 并且Content-Type: 为 application/x-www-form-urlencoded 通常用于接收文件
  3. @RequestPart 注解可以用来替换 @RequestParam 接收文件以及其他更为复杂的数据类型(json xml等等)
  4. @RequestBody 多用于接收post请求 中的请求体的内容,(json数据,大多对应后端的一个实体,或Map类型的数据 等等)
  5. @PathVariable @RequestParam @RequestBody @RequestPart 这四个注解能混合使用,并且每一次注解都支持使用 (required = false)非必须参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值