IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> @RequestBody解密,说点你不知道的 -> 正文阅读

[Java知识库]@RequestBody解密,说点你不知道的

作者:recommend-item-box type_blog clearfix

大家好,我是路人,这是 SpringMVC 系列第 24 篇。

本文将介绍@RequestBody 注解常见的一些用法和原理,这个注解日常用到的特别多。

1、预备知识

  1. 接口测试利器 HTTP Client

  2. 参数解析器 HandlerMethodArgumentResolver 解密

2、@RequestBody 介绍

标注在接口的参数上,用来获取 HTTP 请求 body 中的值,下面通过案例列出常见的用法。

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public?@interface?RequestBody?{

?/**
??* body是不是必须的,默认为true,若不传body,会有异常;若为false,这body可不传
??*/
?boolean?required()?default?true;

}

推荐阅读:尚硅谷 Java 学科全套教程(总 207.77GB)

3、案例 1:使用字符串接收 body 中的数据

3.1、接口代码

注意方法的参数,使用@RequestBody 标注,参数类型是 String,表示以字符串的方式接收 body 的数据。

@RequestMapping("/requestbody/test1")
public?String?test1(@RequestBody?String?body)?{
????System.out.println("body:"?+?body);
????return?"ok";
}

下面来模拟发送 5 种格式的数据,然后看控制台的输出。

3.2、用例 1:发送纯文本数据

Content-Type 用来指定客户端发送的数据的类型。

###?发送纯文本
POST?http://localhost:8080/chat18/requestbody/test1
Content-Type:?text/plain

这里是body部分,欢迎访问我的博客:itsoku.com,上面有更多系列文章

运行,接口内部控制台输出

body:这里是body部分,欢迎访问我的博客:itsoku.com,上面有更多系列文章

3.3、用例 2:发送表单数据,相当于提交表单

Content-Type: application/x-www-form-urlencoded 相当于页面中提交表单,表单中的所有元素会以 name=value&name=value 的方式拼接起来,然后在进行 urlencoded,之后丢在 body 中发送。

###?发送表单数据,相当于提交表单
POST?http://localhost:8080/chat18/requestbody/test1
Content-Type:?application/x-www-form-urlencoded

name=路人&blogs=itsoku.com

运行输出如下,可以看出来是乱码的格式,是由于被中文被 urlencoded 编码了。

body:name=%E8%B7%AF%E4%BA%BA&blogs=itsoku.com

3.4、用例 3:发送 xml 数据

###?发送xml数据
POST?http://localhost:8080/chat18/requestbody/test1
Content-Type:?text/xml

<CourseList>
????<Course>Java高并发系列</Course>
????<Course>MyBatis系列</Course>
????<Course>MySQL系列</Course>
????<Course>Spring高手系列</Course>
????<Course>分布式事务高手系列</Course>
</CourseList>

运行,控制台输出

body:<CourseList>
????<Course>Java高并发系列</Course>
????<Course>MyBatis系列</Course>
????<Course>MySQL系列</Course>
????<Course>Spring高手系列</Course>
????<Course>分布式事务高手系列</Course>
</CourseList>

3.5、用例 4:发送 json 数据

###?发送json数据
POST?http://localhost:8080/chat18/requestbody/test1
Content-Type:?application/json;charset=UTF-8

{
??"blog":?"itsoku.com",
??"course":?[
????"Spring高手系列",
????"MySQL系列",
????"高并发系列"
??]
}

运行,控制台输出

body:{
??"blog":?"itsoku.com",
??"course":?[
????"Spring高手系列",
????"MySQL系列",
????"高并发系列"
??]
}

从上面可以看出,接口参数 body 的值为 http 请求 body 中的原始数据。

推荐阅读:2021 最新版 Java 微服务学习线路图 + 视频

4、案例 2:使用对象接收 json 格式的数据

4.1、用法

发送 json 格式的数据,这种用到的比较多,http 请求发送这种数据,有 3 点要求:

  1. Content-Type 的值需要为:application/json;charset=UTF-8,告诉服务器端客户端 body 中的数据是 json 格式 & UTF-8 编码

  2. body 中数据为 json 格式

  3. 接口端用对象接收,参数使用@RequestBody 标注

4.2、接口代码

@RequestMapping("/requestbody/test2")
public?String?test2(@RequestBody?User?user)?{
????System.out.println("user:"?+?user);
????return?"ok";
}

User 类

public?class?User?{
????private?String?name;
????private?Integer?age;
????private?List<String>?skills;

????//省略get、set

????@Override
????public?String?toString()?{
????????return?"User{"?+
????????????"name='"?+?name?+?'\''?+
????????????",?age="?+?age?+
????????????",?skills="?+?skills?+
????????????'}';
????}
}

4.3、调用接口

重点注意了,头中需要加上Content-Type: application/json

###?发送json数据,后端用对象接收
POST?http://localhost:8080/chat18/requestbody/test2
Content-Type:?application/json;charset=UTF-8

{
??"name":?"路人",
??"age":?35,
??"skills":?[
????"高并发",
????"Spring",
????"分布式事务",
????"MQ",
????"MySQL"
??]
}

4.4、控制台输出

user:User{name='路人',?age=35,?skills=[高并发,?Spring,?分布式事务,?MQ,?MySQL]}

推荐阅读:阿里技术大佬整理的《Spring 学习笔记.pdf》

5、案例 3:使用 Resource 资源对象接收

5.1、用法

有时候,我们想以流的方式接收 body 中的数据,那么可以参考下面的写法,参数类型为[ByteArrayResource,InputStreamResource]这2种类型即可,第一种类型获取的是一个字节数组,第二个是一个 InputStream 输入流。

比如我们需要快速上传文件到阿里云,那么接口接收到客户端的流之后,直接将流转发到 oss,效率更高。

/**
?*?参数为如果为?org.springframework.core.io.Resource?类型,
?*?则只能为Resource的[ByteArrayResource,InputStreamResource]这2种子类型:
?*
?*?@param?body
?*?@return
?*?@throws?IOException
?*/
@RequestMapping("/requestbody/test3")
public?String?test3(@RequestBody?InputStreamResource?body)?throws?IOException?{
????String?content?=?IOUtils.toString(body.getInputStream(),?"UTF-8");
????System.out.println("content:"?+?content);
????return?"ok";
}

5.2、调用接口

###?后端使用Resource接收数据
POST?http://localhost:8080/chat18/requestbody/test3
Content-Type:?text/plain;charset=UTF-8

后端使用Resource接收数据

5.3、控制台输出

content:后端使用Resource接收数据

推荐阅读:阿里大佬的《MySQL 学习笔记高清.pdf》

6、案例 4:以字节数组接受数据

6.1、代码

/**
?*?使用字节数组接收
?*
?*?@param?bodyBytes
?*?@return
?*/
@RequestMapping("/requestbody/test4")
public?String?test4(@RequestBody?byte[]?bodyBytes)?{
????System.out.println("body长度(bytes):"?+?bodyBytes.length);
????System.out.println("body内容:"?+?new?String(bodyBytes));
????return?"ok";
}

6.2、调用接口

###?后端使用字节数组接收数据
POST?http://localhost:8080/chat18/requestbody/test4
Content-Type:?text/plain;charset=UTF-8

itsoku.com

6.3、控制台输出

body长度(bytes):10
body内容:itsoku.com

推荐阅读:2021 版 java 高并发常见面试题汇总.pdf

7、案例 5:使用 HttpEntity 接收数据

7.1、HttpEntity:含有头和 body 信息

如果想同时拿到头和 body 的数据,可以使用,org.springframework.http.HttpEntity来接收数据,这个类中包含了头和 body 的信息,body 是一个泛型,http 请求的数据会被转换为 body 对应的 T 类型。

c08a10995bc00cf1a857f42caa55521c.png

7.2、案例代码

注意:HttpEntity 类型的参数不要用@RequestBody 标注。

@RequestMapping("/requestbody/test5")
public?String?test5(HttpEntity<User>?httpEntity)?{
????//header信息
????HttpHeaders?headers?=?httpEntity.getHeaders();
????System.out.println("headers:"?+?headers);
????//body中的内容会自动转换为HttpEntity中泛型指定的类型
????User?user?=?httpEntity.getBody();
????System.out.println("body:"?+?user);
????return?"ok";
}

7.3、调用案例接口

###?发送json数据,后端用HttpEntity<User>接收
POST?http://localhost:8080/chat18/requestbody/test5
Content-Type:?application/json;charset=UTF-8

{
??"name":?"路人",
??"age":?35,
??"skills":?[
????"高并发",
????"Spring",
????"分布式事务",
????"MQ",
????"MySQL"
??]
}

7.4、控制台输出

headers:[content-type:"application/json;charset=UTF-8", content-length:"130", host:"localhost:8080", connection:"Keep-Alive", user-agent:"Apache-HttpClient/4.5.12 (Java/11.0.10)", accept-encoding:"gzip,deflate"]
body:User{name='路人', age=35, skills=[高并发, Spring, 分布式事务, MQ, MySQL]}

推荐阅读:Idea 快捷键大全.pdf

8、案例 6:使用 RequestEntity 接受数据

8.1、RequestEntity:包含更多请求信息(头、method、url,body)

RequestEntity 的用法和案例 5 中的 HttpEntity 用法类似,RequestEntity 继承了 HttpEntity,包含了更多的信息,比RequestEntity多了 2 个 http 请求信息(method 和 url)

deafe76488fd74c783ad5a244b09d6db.png

8.2、案例代码

@RequestMapping("/requestbody/test6")
public?String?test6(RequestEntity<User>?requestEntity)?{
????//请求方式
????HttpMethod?method?=?requestEntity.getMethod();
????System.out.println("method:"?+?method);
????//请求地址
????URI?url?=?requestEntity.getUrl();
????System.out.println("url:"?+?url);
????//body的类型,即RequestEntity后面尖括号中的类型
????Type?type?=?requestEntity.getType();
????System.out.println("body的类型,即RequestEntity后面尖括号中的类型:"?+?type);
????//header信息
????HttpHeaders?headers?=?requestEntity.getHeaders();
????System.out.println("headers:"?+?headers);
????//body中的内容会自动转换为HttpEntity中泛型指定的类型
????User?user?=?requestEntity.getBody();
????System.out.println("body:"?+?user);
????return?"ok";
}

8.3、调用案例接口

###?发送json数据,后端用对象接收
POST?http://localhost:8080/chat18/requestbody/test6
Content-Type:?application/json;charset=UTF-8

{
??"name":?"路人",
??"age":?35,
??"skills":?[
????"高并发",
????"Spring",
????"分布式事务",
????"MQ",
????"MySQL"
??]
}

8.4、控制台输出

method:POST
url:http://localhost:8080/chat18/requestbody/test6
body的类型,即RequestEntity后面尖括号中的类型:class com.javacode2018.springmvc.chat18.controller.RequestBodyController$User
headers:[content-type:"application/json;charset=UTF-8", content-length:"130", host:"localhost:8080", connection:"Keep-Alive", user-agent:"Apache-HttpClient/4.5.12 (Java/11.0.10)", accept-encoding:"gzip,deflate"]
body:User{name='路人', age=35, skills=[高并发, Spring, 分布式事务, MQ, MySQL]}

9、@RequestBody 还可以如何使用呢?

这里留给大家去研究,大家在运行一下案例 1 中的用例 1

###?发送纯文本
POST?http://localhost:8080/chat18/requestbody/test1
Content-Type:?text/plain

这里是body部分,欢迎访问我的博客:itsoku.com,上面有更多系列文章

控制台有更详细的输出如下,注意里面的RequestResponseBodyMethodProcessor,这个就是@ReqeustBody类型的参数处理器,@ReqeustBody标注的参数的值都是有这个类来解析请求得到的,大家可以去看看这个类的代码,debug 一番,就知道@ReqeustBody还有那些更炫的用法了。

23:17:05.595?[http-nio-8080-exec-9]?DEBUG?org.springframework.web.servlet.DispatcherServlet?-?POST?"/chat18/requestbody/test1",?parameters={}
23:17:05.595?[http-nio-8080-exec-9]?DEBUG?org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping?-?Mapped?to?com.javacode2018.springmvc.chat18.controller.RequestBodyController#test1(String)
23:17:05.596 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read "text/plain;charset=UTF-8" to ["这里是body部分,欢迎访问我的博客:itsoku.com,上面有更多系列文章"]
body:这里是body部分,欢迎访问我的博客:itsoku.com,上面有更多系列文章
23:17:05.597?[http-nio-8080-exec-9]?DEBUG?org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor?-?Using?'text/plain',?given?[*/*]?and?supported?[text/plain,?*/*,?application/json,?application/*+json]
23:17:05.597?[http-nio-8080-exec-9]?DEBUG?org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor?-?Writing?["ok"]
23:17:05.598?[http-nio-8080-exec-9]?DEBUG?org.springframework.web.servlet.DispatcherServlet?-?Completed?200?OK

主要有 5 行日志,每行日志这里做一下解释

第 1 行:接收到了请求,请求的信息(url,参数)

第 2 行:找到了能够处理请求的方法,即 RequestBodyController#test1(String)方法可以处理当前请求

第 3 行:参数解析器,@RequestBody 对应的是 RequestResponseBodyMethodProcessor

第 4 行:接口中 System.out.println 输出的内容

第 5 行:返回值处理器,这个以后会有专题讲解

10、@RequestBody 原理

@RequestBody 标注的参数取值是由RequestResponseBodyMethodProcessor#resolveArgument方法处理的,可以去看源码。

11、代码位置及说明

11.1、git 地址

https://gitee.com/javacode2018/springmvc-series

11.2、本文案例代码结构说明

c663b22d228da4b959cfaecbad4942cc.png

12、SpringMVC 系列目录

  1. SpringMVC 系列第 1 篇:helloword

  2. SpringMVC 系列第 2 篇:@Controller、@RequestMapping

  3. SpringMVC 系列第 3 篇:异常高效的一款接口测试利器

  4. SpringMVC 系列第 4 篇:controller 常见的接收参数的方式

  5. SpringMVC 系列第 5 篇:@RequestBody 大解密,说点你不知道的

  6. SpringMVC 系列第 6 篇:上传文件的 4 种方式,你都会么?

  7. SpringMVC 系列第 7 篇:SpringMVC 返回视图常见的 5 种方式,你会几种?

  8. SpringMVC 系列第 8 篇:返回 json & 通用返回值设计

  9. SpringMVC 系列第 9 篇:SpringMVC 返回 null 是什么意思?

  10. SpringMVC 系列第 10 篇:异步处理

  11. SpringMVC 系列第 11 篇:集成静态资源

  12. SpringMVC 系列第 12 篇:拦截器

  13. SpringMVC 系列第 13 篇:统一异常处理

  14. SpringMVC 系列第 14 篇:实战篇:通用返回值 & 异常处理设计

  15. SpringMVC 系列第 15 篇:全注解的方式 ?&? 原理解析

  16. SpringMVC 系列第 16 篇:通过源码解析 SpringMVC 处理请求的流程

  17. SpringMVC 系列第 17 篇:源码解析 SpringMVC 容器的启动过程

  18. SpringMVC 系列第 18 篇:强大的 RequestBodyAdvice 解密

  19. SpringMVC 系列第 19 篇:强大的 ResponseBodyAdvice 解密

  20. SpringMVC 系列第 20 篇:RestFull 详解

  21. SpringMVC 系列第 21 篇:接口调用过利器 RestTemplate

  22. SpringMVC 系列第 22 篇:参数解析器 HandlerMethodArgumentResolver 解密

  23. SpringMVC 系列第 23 篇:@RequestParam 用法及原理详解

13、更多系列文章

  1. Spring 高手系列(共 56 篇)

  2. Java 高并发系列(共 34 篇)

  3. MySql 高手系列(共 27 篇)

  4. Maven 高手系列(共 10 篇)

  5. Mybatis 系列(共 12 篇)

  6. 聊聊 db 和缓存一致性常见的实现方式

  7. 接口幂等性这么重要,它是什么?怎么实现?

  8. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!

14、最新资料

  1. 尚硅谷 Java 学科全套教程(总 207.77GB)

  2. 2021 最新版 Java 微服务学习线路图 + 视频

  3. 阿里技术大佬整理的《Spring 学习笔记.pdf》

  4. 阿里大佬的《MySQL 学习笔记高清.pdf》

  5. 2021 版 java 高并发常见面试题汇总.pdf

  6. Idea 快捷键大全.pdf

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:07:02  更:2021-12-06 15:07:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:54:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码