@PathVariable、@RequestBody和@RequestParam使用场景及区别
发布日期:2022-03-30 18:18:28 浏览次数:59 分类:博客文章

本文共 5528 字,大约阅读时间需要 18 分钟。

SpringMVC数据绑定接收复杂数据处理方案

常用于数据绑定的几个注解@PathVariable,@RequestBody@RequestParam,本文配合postman,讲解常见的前后台数据交互中的一些数据绑定的问题

@PathVariable

PathVariable是路径变量的意思,这个注解主要作用在请求URL路径上的数据绑定,默认传递数值写在URL上,SpringMVC就可以获取到

  • 支持请求方式:GET
  • 参数传递:在URL上直接传递
@RequestMapping("/Student")@RestControllerpublic class DataBindController {    @Autowired    private StudentService studentService;    @GetMapping("/getStudent/{id}")    public Student getStudentById(@PathVariable Integer id){        Student student = studentService.getStudentById(id);        return student;    }}

@RequestBody

RequestBody是请求体的意思,这个注解作用在请求体的数据绑定,并且数据必须在写在请求体中,还要以JSON的数据格式发送才符合条件

该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;

  • 支持请求方式:GET,POST,PUT,DELETE
  • 参数传递:在Body中传递
  • 支持的Content-Type:json
@PostMapping("/addStudent")    public Student addStudent(@RequestBody Student student){        System.out.println(student);        return student;    }

@RequestParam

RequestParam是请求参数的意思,这个注解的作用在请求路径和请求体中的数据,因为使用request.getParameter()方式获取参数

所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值

  • 支持请求方式:GET,POST,PUT,DELETE
  • 参数传递:在Body中传递
  • 支持的Content-Type:json

在请求体中的参数必须指定是form-data或者x-www-form-urlencoded,这两种方式是以表单的形式提交数据,使用这两种方式

会将表单内的数据转换为键值对,&分隔形式封装在请求体中传送给后台,前者和后者的区别是在于对非ASCII码字符的转码,

前者是直接发送,后者是转码成百分号发送

三个注解小结

注解 请求参数位置 请求方式 支持的Content-Type 请求示例
@PathVariable Url Get Get请求没有Content-Type /students/1
@RequestParam Url和Body Get/Post/Put/Delete/Patch form-data,x-www-form-urlencoded /students?name=zs&age=23
@RequestBody Body Post/Put/Delete/Patch application/json {"id":1,"name":"zs","age":23}

三个注解的源码和使用场景:

@PathVariable

这个注解我一般在工作中,会用在单个对象的查询上,比如要根据ID值查询学生信息,就会在Postman发送GET请求,后台使用@PathVariable接收

  • 优点:适合接收简单类型的数据绑定,如int,string这两个常用
  • 缺点:id暴露在url上,对于不方便泄露ID的值请求,最好不要使用。只支持Get方式,请求方式有局限性,不支持复杂数据类型,自定义数据类型

源码

@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface PathVariable {    /**     * 参数名称     */    String value() default "";}

源码解析

  • @PathVariable注解源码中只有一个参数,不填的默认是绑定到与路径参数同名的形参变量

  • 如果要接收多个路径变量,则需要声明多个@PathVariable变量

@RequestMapping("/Student/{name}/{age}")  public Object getStudentInfo (@PathVariable String name,@PathVariable Integer age){      //...  }

使用解析

  • POSTMAN发送的链接:http:
  • 后端接收参数:/Student/getStudent/{id},这里的id是路径上的参数,传什么值接收什么值
  • 后端映射值:@PathVariable Integer id 这里的方法参数id要与路径变量参数id同名,因为@PathVariable没有指定别名的注解变量

@RequestParam

这个注解我一般在工作中,会用在组合查询多个对象,比如跟据姓名模糊查询和性别组合查询筛选学生,就会发送POST请求,后台使用RequestParam接收

  • 优点:支持常用多种请求方式,请求参数可以封装在请求体中较为安全
  • 缺点:id暴露在url上,对于不方便泄露ID的值请求,最好不要使用。只支持Get方式,请求方式有局限性

源码

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RequestParam {     /**     * 参数名称(和value同等意思)     */    @AliasFor("name")    String value() default "";     /**     * 参数名称 (和name同等意思)     */    @AliasFor("value")    String name() default "";     /**     * 是否必选(默认必选)     */    boolean required() default true;     /**     * 参数默认值     */    String defaultValue() default ValueConstants.DEFAULT_NONE; }

源码解析

@RequestParam总体上来说,该注解类拥有三个参数:

  • value、name 属性都标识请求参数名(必须配置)

  • required:参数是否必传,默认为 true,可以设置为非必传 false;(如果设置了必传或默认,请求未传递参数,将会抛出异常)

  • defaultValue:参数默认值,如果设置了该值,required 将会自动设置为 false

使用解析

  • get请求的 requestHeaders 中 content-type 这个字段,使用 form-data 表单形式携带参数请求

  • Spring中的@RequestParam注解接收的参数大多数场景是来自Request Headers中,

  • 即请求头,也就是url中,格式为:http://localhost:8080?name=zs&age=23,由于 url 长度有限制,所以参数需要限制数量和值得长度

@RequestBody

源码

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RequestBody {     /**     * 默认参数必传     */    boolean required() default true; }

源码解析

  • @RequestBody注解只拥有一个参数
  • required 默认为 true,即对象中的属性必须有一个要传,否则会抛出异常

使用解析

  • post请求的requestHeaders请求头中有content-type字段,一般用来处理:applicatin/json格式的参数;

  • Spring中的@RequestBody注解是用来接收请求体中的参数数据,即requestBody请求体中,故不受参数数据长度的限制;

补充HTTP知识:Post、Get、Put、Delete

Http协议常用的四种请求方式:Post、Get、Put、Delete等;其中Put、Delete请求方式很少见,都可用Post方式代替!

  • 对数据库而言: get 请求不修改数据库,只是查询。Post是增加记录,put是更新,Delete数据库删除;
  • Put,Post,Delete 方式的请求参数会直接放在requestBody里;
  • 处理 request uri 部分的注解,路径参数变量:@PathVariable;
  • 处理request header部分的注解: @RequestHeader, @CookieValue,@RequestParam;
  • 处理request body部分的注解:@RequestParam, @RequestBody;  
  • 综上所述:@RequestParam注解既可以接收Get方式的请求头中的参数,也可以接收Post方式的请求体中的参数;

补充HTTP知识: Content-Type与Accept

--------Response Headers-----------HTTP/1.1 200 OKServer: Apache-Coyote/1.1If-Modified-Since: 0expire: 0Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Tue, 17 Nov 2020 05:48:54 GMT--------Request Headers-----------POST /student/update HTTP/1.1Host: localhost:9002Connection: keep-aliveContent-Length: 21Pragma: no-cacheCache-Control: no-cacheAccept: application/jsonX-Requested-With: XMLHttpRequestUser-Agent: Chrome/86.0.4240.75 Mobile Safari/537.36Content-Type: application/json

Accept

Accept代表发送希望接受的数据类型

比如:Accept:application/json;

比如我们用浏览器发送请求中,请求头Request Headers带有Accept:application/json; ,

那就是表明浏览器发送这个请求,希望服务器传送回的数据格式是json数据格式

Content-Type

Content-Type代表发送端发送的数据类型

比如:Content-Type:application/json;

Response Headers带有Content-Type: application/json就代表服务器希发送数据类型是json类型

Request Headers带有Content-Type: application/json就代表服务器希发送数据类型是json类型

上述报文解释

浏览器发送了POST请求,这次请求发送的数据格式是JSON数据给是,希望服务器能返回JSON的数据格式

服务器发送返回了JSON形式的数据格式数据给浏览器

常见Content-Type媒体类型

Get请求的 headers 中没有 content-type 这个字段,Put、Delete和Post 请求的headers 是有 content-type 这个字段的

常见Content-Type媒体类型如下:

  • application/x-www-form-urlencoded 这种就是一般的文本表单用 post 传地数据,

    只要将得到的 data 用 @RequestParam 或 request.getParamter() 获取即可;

  • multipart/form-data ,用于文件上传,此时 form 的 enctype 属性必须指定为 multipart/form-data;

  • application/json,将数据以json对象的格式传递;

  • text/xml;

转载地址:https://www.cnblogs.com/codeluojay/p/13997558.html 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:一文带你了解常见的单例设计模式写法,学会了能跟面试官扯皮
下一篇:SpringBoot+Vue-admin-template 实现增删改查

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月09日 17时23分31秒