RestTemlate源码分析及工具类设计
先说个大概的结构:
- RestTemlate的所有方法最终调用的是
doExecute()
,层层向外封装 - 其中
exchange()
适合用来封装成工具类,他的返回值是ResponseEntity postForObject()
和postForEntity
本质上一样,只是后者
对运行结果进行了封装,返回的也是ResponseEntity,类似于lambda表达式中的Option类
1.本文的源码分析部分采用“从外到内”的顺序进行分析
2.类似postForObject和getForObject这种的区别仅仅是GET请求和POST请求的区别,本文仅分析POST请求的
3.postFroLocation()方法是返回一个URI,不是本文的重点
1.返回值ResponseEntity有什么用?
1.1 postForObject()和postForEntity()
看源码的注释部分,几乎一致,也就是两个方法基本没有什么区别
其中一个返回值是封装类ResponseEntity
重要!!:关于提取响应的方式
postForObject:HttpMessageConvertExtractor
postforEntity:ResponseExtractor
这两个Extractor类都有一个公共接口extractData
,他在execute方法执行的时候被调用,用于获取HTTP响应的数据,只是在实现上,一个只获取响应体,另一个还要额外获取headers和status
1.2ResponseEntity的重要参数
既然这个封装类有状态码status,响应头headers,那么一定在某个地方,getForObject没有去指定而getForEntity指定了(这时候应该猜到是extractData()方法,将在后面讨论)
1.2.1状态码
1.2.2 getBody() getHeaders()
直接获取上面两个参数,不再赘述
1.3ResponseEntity是如何封装返回值的?
1.3.1 responseExtrator.extractData(response)提取数据
- 已知,最终都是调用doExecute()
- 两个方法到这里的Extractor都是非空的,都是一定要执行,两个执行逻辑不同
1.3.2extractDatad抽象方法
这里直接看getForEntity对应的ResponseEntityResponseExtractor
,即封装了status和headers的执行过程
因此,只有返回值是Entity的才有headers和status,否则像getForObject这种方法返回的只是一个响应体
1.3.3公共的extractData()逻辑
即两个都会调用的,上面那么打红框的,通篇都是只针对了响应体进行操作,没有涉及任何的headers和status
1.3.4nonNull检验是否为空
如果是封装为Entity,那么还要再加一层判断方法
1.4小结
-
到此为止我们分析了为什么getForObject()返回的只有响应体,而getForEntity()返回的包括了响应体 响应头 响应状态
-
而getForEntity()和exchange()返回的都是ResponseEntity对象,因此第二点引出二者的区别
-
get和post请求只有一个区别,后续会演示如何使用API
2.exchange()和xxxtForEntity()
- 可以看出区别就是
requestEntity
请求参数 - 至于请求方法method不是主要矛盾
- 这三个方法,参数所对应的含义如下:
第一个:url
对于exchange,第二个参数是请求方式自定义
第三个:请求体参数,exchange和post有,get没有,用map或dto或requestEntity封装
第四个:返回值类型
第五个:路径参数,对应的是@RequestParam和@PathVariable,使用方式是在url中用{}占位,类似logger的{},也类似String.format()中的%s占位,因此Object…uriVariable