@RequestBody、@RequestParam 、@PathVariable、@RequestPart àì夳堔傛蜴生んèń 2022-12-11 09:24 238阅读 0赞 ### 文章目录 ### * * 一、@RequestParam(一个方法中能使用多次) * * 1. 简介 * 2. 实例 * 二、 @RequestBody(一个方法中能使用多次,但是建议只使用一次) * * 1. 简介 * 2.实例 * 三、@PathVariable (一个方法中可以使用多次) * * 1. 简介 * 四、@RequestPart(复杂的请求场景) * * 1.简介 * 2.实例 * * @RequestPart-同时上传文件和json的解决方案 * 多文件 * 五、总结 * * 1. 小结 * 2. 分类 * 六、 实际使用情况 ## 一、@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) { } ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MzQxMjAz_size_16_color_FFFFFF_t_70_pic_center] 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上是这样调用的: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MzQxMjAz_size_16_color_FFFFFF_t_70_pic_center 1] ## 五、总结 ## ### 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. 分类 ### <table> <thead> <tr> <th>注解</th> <th>GET</th> <th>POST</th> <th>支持的Content-Type</th> <th>不支持的Content-Type</th> </tr> </thead> <tbody> <tr> <td>@RequestBody</td> <td>✘</td> <td>✔</td> <td>application/json,application/xml</td> <td>application/x-www-form-urlencoded</td> </tr> <tr> <td>@RequestParam</td> <td>✔</td> <td>✔</td> <td>multipart/form-data,application/x-www-form-urlencoded</td> <td>…</td> </tr> <tr> <td>@RequestPart</td> <td>✔</td> <td>✔</td> <td>multipart/form-data,application/x-www-form-urlencoded,application/json,application/xml</td> <td>…</td> </tr> <tr> <td>@PathVariable</td> <td>✔</td> <td>✔</td> <td>…</td> <td>…</td> </tr> </tbody> </table> ## 六、 实际使用情况 ## 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)非必须参数 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MzQxMjAz_size_16_color_FFFFFF_t_70_pic_center]: /images/20221123/4cb09adad9c34bde961a05f7bbe7b40f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1MzQxMjAz_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20221123/668afa2cfb3a4e0891df3c8758b94df9.png
还没有评论,来说两句吧...