zoukankan      html  css  js  c++  java
  • SpringBoot传递单一参数时@RequestParam和@RequestBody的区

    用SpringBoot框架做项目时,经常需要前端给后端传递参数,如果需要多条参数,通常的做法是把这些参数封装为一个对象来传递,前端用POST方式调用。但有时会遇到后端只需要一条参数(比如一个String)的情况,此时如果还封装为一个对象,有些麻烦;最好的办法是用GET方式调用,直接把参数拼接在url后面。然而,一般项目都有统一的接口规范,要求接口都要用POST方式,此时就遇到一个问题:controller方法上到底是用@RequestParam注解还是用@RequestBody注解?

     之前对这两个注解的区别,只有一个粗枝大叶的理解——@RequestParam针对单一的参数,而@RequestBody针对多个参数封装为一个对象,问了身边几个同事,大概也都是这种理解。但是,实际测试中(使用Postman),当我用@RequestParam接受String的单一参数时,前端给我传递的参数却接收不到。于是决定通过实验,彻底搞明白二者的区别(针对单一参数、且规定使用POST方式的场景)。实验的过程是分别用两个注解去接受前端传递的一个名为content的String。

    实验一:使用@RequestParam注解

    Controller方法代码:(省略其他部分以及返回值Result代码)

    @RequestMapping(value="/requestParam", method= RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Result<String> requestParam(@RequestParam("content") String content) {
    System.out.println("content:"+content);
    return success(new Result<String>(), content);
    现在我用postman来测试几种可能的参数传递方式:

    1. 在Body的raw里面传递,也是最通常的传参方式:

    body-raw

    结果是接收不到(不管是用text还是json等各种文本形式)!

     { "timestamp": 1544798083474,
        "status": 400,
        "error": "Bad Request",
        "exception": "org.springframework.web.bind.MissingServletRequestParameterException",
        "message": "Required String parameter 'content' is not present",
        "path": "/testParam/requestParam"
      }

    2. 在Headers里通过key-value的形式传递。这是网上一些帖子里说的方式。

    Headers方式

    但结果还是接收不到!和上面一样报错400。

    关于这一点,网上有些帖子里说@RequestParam的参数会写到Headers里,可见是错误的,并非在Headers里,还是在Body里。

    3. 在Body的form-data里通过key-value的形式传递,可以接收!

    form-data

    但是,前端在传参时,是无法向这个form-data里传递参数的,所以这种方法可以被排除。

    4. 在url后问号拼接参数。和很多人一样,之前一直根深蒂固地认为只有GET方式才能用url问号传参,POST方式不行,但事实证明在这里问号传参POST方式同样能接收到。如图:

    问号传参

    虽然能接受到参数,但前端也有统一的规范,一般不使用问号传参的方式,所以这种方法也被排除。

    实验二:使用@RequestBody注解

    @RequestMapping(value="/requestBody", method= RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Result<String> requestBody(@RequestBody String content) {
    System.out.println("content:"+content);
    return success(new Result<String>(), content);
    }
     既然是Body,自然不能在header里传参,也不能在url里问号传参。至于Body的form-data,经测试也无效。所以,这里只有唯一一种方式,就是将参数直接写在Body的raw模式下,可以接收到,而且最好选择Text而非JSON(application/json),如图:

    body

     注意:这里body体里面传什么内容,后台就会原样接收,所以不要写成content: XXX这种键值对形式,而应直接把String的内容写在body体里。

     总结:

    对于传递单一参数(最典型的是String)的场合,最简便的方法是用GET请求。但鉴于很多项目接口统一要求使用POST方式,此时不能使用@RequestParam方式,因为此方式前端传递的参数后端无法接收;而只能采用@RequestBody注解,直接将需要的参数内容写入Body体,后端即可正常获取!
          <div marginwidth="0" marginheight="0" scrolling="no" width="100%">
              <div>
                <div id="kp_box_87" data-pid="87"><iframe src="https://adaccount.csdn.net/#/preview/555?m=AcitfvHbAEJcpmUJHcpJicbAooHAAJJJbnppmtAJpyHivLSLAvASvbHtQtWfSpbADXbJfpEbbEEnSSpncoSfALLntpHDJtQpnntQ&amp;k=" frameborder="0" width="100%" height="75px" scrolling="no"></iframe><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?d=2&amp;k=&amp;m=AcitfvHbAEJcpmUJHcpJicbAooHAAJJJbnppmtAJpyHivLSLAvASvbHtQtWfSpbADXbJfpEbbEEnSSpncoSfALLntpHDJtQpnntQ"></div>
              </div>
          </div>
        <!-- <div class="question_wrap"><span>问题点数:</span><em>分</em></div> -->
    

    原文地址:https://bbs.csdn.net/topics/392660349

  • 相关阅读:
    itoa
    sprintf用法 [转载]
    atoi 与 itoa的实现
    数组排序总结(冒泡,选择,插入,希尔)
    XML入门精解之文件格式定义(DTD)
    malloc()函数的工作机制 结构体的总结
    字符串指针与字符数组(ZT)
    sprintf函数你了解有多深!
    sprintf
    sql ldr 笔记
  • 原文地址:https://www.cnblogs.com/jpfss/p/11446452.html
Copyright © 2011-2022 走看看