最近在编写项目的过程中,老出现前后端传递参数格式不一致、不统一的问题,对于一个已经快工作一年的Java程序员来说,实属不合格,所以我就下来好好研究了一下@RequestParam和@RequestBody的区别,避免大家遭遇同等错误;

一 @RequestParam注解

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

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

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

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

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

(2)@RequestParam注解获取的参数放在请求哪?

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

  b)Spring中的@RequestParam注解接收的参数大多数场景是来自requestHeaders中,即请求头,也就是url中,格式为:http://localhost:8080?name=yc&age=23,由于 url 长度有限制,所以参数需要限制数量和值得长度;

(3)如何使用:

  使用一:利用Postman工具,使用form-data提交Get请求

  

  执行代码:

@RequestMapping(value = "/test", method = RequestMethod.GET)
public void test(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("age") Integer age) {
log.info("id = {}, name = {}, age = {}", id, name, age);
}

  结果:

id = 1, name = yc, age = 23

  使用二:不使用@RequestParam注解直接进行对象属性赋值(不推荐使用,容易和@ReuqestBody混淆)

  代码执行:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
} @RequestMapping(value = "/test", method = RequestMethod.GET)
public void test(User user) {
log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());
}

  结果:

id = 1, name = yc, age = 23

(4)使用场景:

  a)请求是为了查找资源,获取服务器数据;

  b)请求结果无持续性的副作用,例如:不会对数据库进行添加、修改、删除操作;

  c)传入的参数不会太长,因为Get请求可能会产生很长的URL,或许会超过某些浏览器与服务器对URL的长度限制,导致请求失败;

二、@RequestBody注解

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

(1)@RequestBody注解只拥有一个参数:

  required 默认为 true,即对象中的属性必须有一个要传,否则会抛出异常:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

(2)@RequestBody注解获取的参数在请求哪?

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

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

(3)如何使用?

  使用Postman工具发送json格式的数据:

  

  执行代码:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age; } @RequestMapping(value = "/test", method = RequestMethod.POST)
public void test(@RequestBody User user) {
log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());
}

  结果:

id = 1, name = yc, age = 23

(4)使用场景:

  a)请求的结果有持续性作用,例如:对数据库添加、更新、删除操作;

  b)若使用Get请求,表单参数过长;

  c)要传送的数据不是采用7位的ASCII编码;

测试三:使用Post请求,@RequestParam也可以接收参数;

  注意:也可以使用这种方式用,发送Post请求,参数拼接到url之后,这是因为协议之间没有做严格的区分,但这种方式不建议使用,这种方式就使用Get方式即可。例如:localhost:8888/optimus-prime/project/test?id=1&name=yc&age=23 使用浏览器请求数据,这种方式Get请求,但后端使用Post方式接收,访问不成功!

  

  执行代码:

    @PostMapping(value = "/test")
public void test(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("age") Integer age) {
log.info("id = {}, name = {}, age = {}", id, name, age);
}

  结果:

id = 1, name = yc, age = 12

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

  a)对数据库而言: get 请求不修改数据库,只是查询。Post是增加记录,put是更新,Delete数据库删除;

  b)Put,Post,Delete 方式的请求参数会直接放在requestBody里;

  c)处理 request uri 部分的注解,路径参数变量:@PathVariable;

  d)处理request header部分的注解:   @RequestHeader, @CookieValue,@RequestParam;

  e)处理request body部分的注解:@RequestParam, @RequestBody;  

综上所述:@RequestParam注解既可以接收Get方式的请求头中的参数,也可以接收Post方式的请求体中的参数;

额外知识2:get请求的 headers 中没有 content-type 这个字段,post 的 content-type 有 :

  a)application/x-www-form-urlencoded  这种就是一般的文本表单用 post 传地数据,只要将得到的 data 用 @RequestParam 或 request.getParamter() 获取即可;

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

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

  d)text/xml;

  e)put 和 delete 请求的headers 是有 content-type 这个字段的,只不过这两个方法类型目前不常用;

每天进步一点点,开心!  

  

灵活运用的@RequestParam和@RequestBody的更多相关文章

  1. springMVC中 @RequestParam和@RequestBody的区别

    首先,不可以同时传进@RequestParam和@RequestBody,好像可以传进两个@RequestParam 如果不加@requestparam修饰,相当于 加上@requestparam且各 ...

  2. springMVC中@RequestParam和@RequestBody的作用

    @RequestParam和@RequestBody是什么区别,估计很多人还是不太清楚, 因为一般用@ RequestParam就足够传入参数了,要说他们区别,就需要知道contentType是什么? ...

  3. Spring MVC常用注解@PathVariable、@RequestHeader、@CookieValue、@RequestParam、@RequestBody、@SessionAttributes、@ModelAttribute

    简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型) A.处理requet uri部分(这里指uri template中 ...

  4. SpringBoot实战(四)获取接口请求中的参数(@PathVariable,@RequestParam,@RequestBody)

    上一篇SpringBoot实战(二)Restful风格API接口中写了一个控制器,获取了前端请求的参数,现在我们就参数的获取与校验做一个介绍: 一:获取参数 SpringBoot提供的获取参数注解包括 ...

  5. post传参params与body的区别(@RequestParam和@RequestBody的区别)

    1.axios post请求  Content-Type默认为 application/x-www-form-urlencoded,我们传递参数的时,params里面的参数(简单的对象,通过 &quo ...

  6. @RequestParam、@RequestBody、@PathVariable区别和案例分析

    一.前言 @RequestParam.@RequestBody.@PathVariable都是用于在Controller层接收前端传递的数据,他们之间的使用场景不太一样,今天来介绍一下!! 二.实体类 ...

  7. springMVC中@RequestParam和@RequestBody注解的用法

    springMVC中@RequestParam注解用在Controller层获解析.提取参数,当然你也可以用request.getParameter("name")来获取参数,而@ ...

  8. @RequestParam、@RequestBody和@ModelAttribute区别

    一.@RequestParamGET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上1. @RequestParam(org.springframework.web.b ...

  9. @RequestParam 和@RequestBody 的区别?

    @RequestParam用来接收: 1 用来处理简单的参数绑定 2 用来接收 Content-Type 是   application/x-www-form-urlencoded (这种格 式的数据 ...

随机推荐

  1. FreeRTOS链表实现

    直接上源码分析 void vListInitialise( List_t * const pxList ){ pxList->pxIndex = ( ListItem_t * ) &( ...

  2. OpenSpiel 随笔 05.14

    ------------恢复内容开始------------ 这两天年总算把自己的游戏写完了,也通过了所有的测试. 我将自己的代码上传到了我的github上, 地址是 https://github.c ...

  3. APP UI自动化测试思路总结

    python+appium自动化测试系列就要告一段落了,本篇博客咱们做个小结. 首先想要说明一下,APP自动化测试可能很多公司不用,但也是大部分自动化测试工程师.高级测试工程师岗位招聘信息上要求的,所 ...

  4. ant-design-vue中tree增删改

    ant-design-vue中tree增删改 1. 使用背景 新项目中使用了ant-design-vue组件库.该组件库完全根基数据双向绑定的模式实现.只有表单组件提供少量的方法.所以,在使用ant- ...

  5. django路径问题

    1. 初始化项目结构 2.创建Django项目 使用pycharm打开项目 1.右击---->编辑配置 > 2.文件---->设置 > 3.文件---->设置 > ...

  6. [Luogu P2831] 愤怒的小鸟 (状压DP)

    题面: 传送门:https://www.luogu.org/problemnew/show/P2831 Solution 首先,我们可以先康一康题目的数据范围:n<=18,应该是状压或者是搜索. ...

  7. C语言100题集合004-统计各个年龄阶段的人数

    系列文章<C语言经典100例>持续创作中,欢迎大家的关注和支持. 喜欢的同学记得点赞.转发.收藏哦- 后续C语言经典100例将会以pdf和代码的形式发放到公众号 欢迎关注:计算广告生态 即 ...

  8. 833. Find And Replace in String —— weekly contest 84

    Find And Replace in String To some string S, we will perform some replacement operations that replac ...

  9. Servlet学习笔记(三)

    目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...

  10. CF1271E Common Number

    数学+二分 连续打了3场$codeforces$,深深的被各种模拟贪心分类讨论的$C$,$D$题给恶心到了 还有永远看到题一脸懵的$B$题 首先考虑画出不同函数值迭代转移的关系,要注意考虑连边是否能成 ...