详解 RestTemplate 操作
转载自:https://blog.csdn.net/itguangit/article/details/78825505
作为开发人员,我们经常关注于构建伟大的软件来解决业务问题。数据只是软件完成工作时
要处理的原材料。但是如果你问一下业务人员,数据和软件谁更重要的话,他们很可能会选择
数据。数据是许多业务的生命之血。软件通常是可以替换的,但是多年积累的数据是永远不能
替换的。
近几年来,以信息为中心的表述性状态转移(Representational State Transfer,REST)已经称为替代传统SOAP Web 服务的流行方案.
SOAP关注的一般是行为和处理,而REST关注的是要处理的数据.
从Spring3.0开始,Spring为创建Rest API提供了良好的支持.
REST提供了一个更简单的可选方案。另外,很多的现代化应用都会有移动或富JavaScript客户端,它们都会使用运行在服务器上REST API。
REST的基础知识
**当谈论REST时,有一种常见的错误就是将其视为“基于URL的Web服务”——将REST作为另一
种类型的远程过程调用(remote procedure call,RPC)机制,就像SOAP一样,只不过是通过简单
的HTTP URL来触发,而不是使用SOAP大量的XML命名空间。**
**恰好相反,REST与RPC几乎没有任何关系。RPC是面向服务的,并关注于行为和动作;而REST
是面向资源的,强调描述应用程序的事物和名词**。
更简洁地讲,**REST就是将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户
端(或者反过来)**。
在REST中,资源通过URL进行识别和定位。至于RESTful URL的结构并没有严格的规则,但是
URL应该能够识别资源,而不是简单的发一条命令到服务器上。再次强调,关注的核心是事
物,而不是行为。
Spring 中如何使用Rest资源
借助 RestTemplate,Spring应用能够方便地使用REST资源
Spring的 RestTemplate访问使用了模版方法的设计模式.
模版方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了接口的不同行为.
RestTemplate定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。
其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。
delete() 在特定的URL上对资源执行HTTP DELETE操作
exchange()
在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中
映射得到的execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
postForEntity()
POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得
到的postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
postForLocation() POST 数据到一个URL,返回新创建资源的URL
put() PUT 资源到特定的URL
实际上,由于Post 操作的非幂等性,它几乎可以代替其他的CRUD操作.
Get请求

RestTemplate 的get方法有以上几个,可以分为两类: getForEntity() 和 getForObject()
首先看 getForEntity() 的返回值类型 ResponseEntity
<T> ResponseEntity<T> getForEntity()
- 1
看一下 ResponseEntity 的文档描述:

可以看到 它继承了HttpEntity. 封装了返回的响应信息,包括 响应状态,响应头 和 响应体.
在测试之前我们首先 创建一个Rest服务,模拟提供Rest数据,这里给出Controller层代码,具体可以查看源码,文章最后会给出:
/**
* @author itguang
* @create 2017-12-17 10:37
**/
@RestController
public class UserController { @Autowired
private UserService userService; @RequestMapping(value = "getAll")
public List<UserEntity> getUser() {
List<UserEntity> list = userService.getAll();
return list;
} @RequestMapping("get/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) { return userService.getById(id);
} @RequestMapping(value = "save")
public String save(UserEntity userEntity) { return "保存成功";
} @RequestMapping(value = "saveByType/{type}")
public String saveByType(UserEntity userEntity,@PathVariable("type")String type) { return "保存成功,type="+type;
} }
测试: getForEntity
- 无参数的 getForEntity 方法
@RequestMapping("getForEntity")
public List<UserEntity> getAll2() {
ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://localhost/getAll", List.class);
HttpHeaders headers = responseEntity.getHeaders();
HttpStatus statusCode = responseEntity.getStatusCode();
int code = statusCode.value();
List<UserEntity> list = responseEntity.getBody();
System.out.println(list.toString());
return list;
}
- 有参数的 getForEntity 请求,参数列表,可以使用 {} 进行url路径占位符
//有参数的 getForEntity 请求,参数列表
@RequestMapping("getForEntity/{id}")
public UserEntity getById2(@PathVariable(name = "id") String id) { ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, id);
UserEntity userEntity = responseEntity.getBody();
return userEntity;
}
- 有参数的 get 请求,使用map封装参数
//有参数的 get 请求,使用map封装参数
@RequestMapping("getForEntity/{id}")
public UserEntity getById4(@PathVariable(name = "id") String id) {
HashMap<String, String> map = new HashMap<>();
map.put("id",id); ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, map);
UserEntity userEntity = responseEntity.getBody(); return userEntity;
}
通过断点调试我们看下 返回的 responseEntity 的信息如图:

因此我们可以获取Http请求的全部信息.
但是,通常情况下我们并不想要Http请求的全部信息,只需要相应体即可.对于这种情况,RestTemplate提供了 getForObject() 方法用来只获取 响应体信息.
getForObject 和 getForEntity 用法几乎相同,指示返回值返回的是 响应体,省去了我们 再去 getBody() .
测试: getForObject
- 无参数的 getForObject 请求
//无参数的 getForObject 请求
@RequestMapping("getAll2")
public List<UserEntity> getAll() {
List<UserEntity> list = restTemplate.getForObject("http://localhost/getAll", List.class); System.out.println(list.toString());
return list; }
- 有参数的 getForObject 请求,使用参数列表
//有参数的 getForObject 请求
@RequestMapping("get2/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) { UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, id); return userEntity;
}
- 有参数的 get 请求,使用map封装请求参数
//有参数的 get 请求,使用map封装请求参数
@RequestMapping("get3/{id}")
public UserEntity getById3(@PathVariable(name = "id") String id) {
HashMap<String, String> map = new HashMap<>();
map.put("id",id); UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, map); return userEntity;
}
Post请求
了解了get请求后,Post请求就变得很简单了,我们可以看到post有如下方法:

测试: postForEntity
- post 请求,保存 UserEntity 对像
//post 请求,提交 UserEntity 对像
@RequestMapping("saveUser")
public String save(UserEntity userEntity) {
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/save", userEntity, String.class);
String body = responseEntity.getBody();
return body;
}
浏览器访问: http://localhost/saveUser?username=itguang&password=123456&age=20&email=123@123.com
我们再次断点调试,查看 responseEntity 中的信息:

- 有参数的 postForEntity 请求
// 有参数的 postForEntity 请求
@RequestMapping("saveUserByType/{type}")
public String save2(UserEntity userEntity,@PathVariable("type")String type) { ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class, type);
String body = responseEntity.getBody(); return body; } // 有参数的 postForEntity 请求,使用map封装
@RequestMapping("saveUserByType2/{type}")
public String save3(UserEntity userEntity,@PathVariable("type")String type) {
HashMap<String, String> map = new HashMap<>();
map.put("type", type); ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class,map);
String body = responseEntity.getBody(); return body; }
我们浏览器访问: localhost/saveUserByType/120?username=itguang&password=123456&age=20&email=123@123.com
就会返回: 保存成功,type=120
详解 RestTemplate 操作的更多相关文章
- linux iostat命令详解 磁盘操作监控工具
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视. 它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况. ...
- Web服务器之Nginx详解(操作部分)
大纲 一.前言 二.Nginx 安装与配置 三.Nginx 配置文件详解 四.Nginx 命令参数 五.配置Nginx提供Web服务 六.配置Nginx的虚拟主机 七.配置Nginx的用户认证 八.配 ...
- 【Tools】VMware虚拟机三种网络模式详解和操作
目录 00. 目录 01. VMware虚拟机三种网络模式 02. Bridged(桥接模式) 03. NAT(地址转换模式) 04. Host-Only(仅主机模式) 00. 目录 @ 参考:htt ...
- 详解文件操作(ifstream、ofstream、fstream)[转]
C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...
- 详解PHP操作Memcache缓存技术提高响应速度的方法
本文转载http://blog.csdn.net/zhihua_w 不错的博客,仅供本人学习之用 一般来说,如果并发量不大的情况,使不使用缓存技术并没有什么影响,但如果高并发的情况,使用缓存技术就显 ...
- Hbase Shell命令详解+API操作
HBase Shell 操作 3.1 基本操作1.进入 HBase 客户端命令行,在hbase-2.1.3目录下 bin/hbase shell 2.查看帮助命令 hbase(main):001:0& ...
- Reg命令使用详解 批处理操作注册表必备
首先要说明:编辑注册表不当可能会严重损坏您的系统.在更改注册表之前,应备份计算机上任何有价值的数据 只有在别无选择的情况下,才直接编辑注册表.注册表编辑器会忽略标准的安全措施,从而使得这些设置会降低性 ...
- Linux setenforce命令详解[SeLinux操作]
SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统. 关闭SELinux 临时生效: 命令临时 ...
- 009-Hadoop Hive sql语法详解4-DQL 操作:数据查询SQL-select、join、union、udtf
一.基本的Select 操作 语法SELECT [ALL | DISTINCT] select_expr, select_expr, ...FROM table_reference[WHERE whe ...
随机推荐
- 【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
概述 在安卓开发中免不了需要播放一点音乐了,音频了.但是这时候有别的应用正在播放,这时候就会出现重音的现象,完全影响用户体验,我们的项目就遇上了这样的尴尬,然后查找了一些文档,记录一下: 管理音频焦点 ...
- 总结 Linux 下安装 PHP 扩展步骤
总结一下 Linux 下安装 PHP 扩展步骤,这里以安装 PHP 的 redis 扩展为例. 一.拿到扩展包下载地址,下载扩展包 pecl 上搜索 redis wget http://pecl.ph ...
- 微信硬件平台(八) 3-0ESP8266向微信服务器请求设备绑定的用户
1调试助手 请求URL: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=自己微信ID&a ...
- jenkins使用5----gi服务器搭建连接
♦安装git ♦服务器创建git用户 [root@localhost home]# id git id: git:无此用户 [root@localhost home]# useradd git [ro ...
- tomcat配置通过域名直接访问项目首页步骤
假设www.ctool.top.ip:192.168.122.135 step 1 申请一个域名并做好DNS解析,或者在hosts文件做域名指向 #vim /etc/hosts www.ctool.t ...
- 论文笔记(一)---翻译 Rich feature hierarchies for accurate object detection and semantic segmentation
论文网址: https://arxiv.org/abs/1311.2524 RCNN利用深度学习进行目标检测. 摘要 可以将ImageNet上的进全图像分类而训练好的大型卷积神经网络用到PASCAL的 ...
- 【转】AlphaGO Zero 原理
原文地址:https://www.hhyz.me/2018/08/08/2018-08-08-AlphaGO-Zero/> 1. 概述 简单来说,AlphaGo Zero 的训练可以分为三个 ...
- C#使用Json.Net遍历Json
StringBuilder builder=new StringBuilder(); builder.AppendLine("{"); builder.AppendLine(&qu ...
- 调整代码生成工具Database2Sharp的Winform界面生成,使其易于列表工具栏的使用。
在Winform界面开发的时候,有时候我们客户喜欢把功能放在列表界面的顶部,这样界面和功能整齐放置,也是一种比较美观的方式,基于这种方式的考虑,改造了代码生成工具的Winform界面生成规则,把增删改 ...
- [翻译] 使用 Visual Studio 2019 来提高每个开发人员的工作效率
[翻译] 使用 Visual Studio 2019 来提高每个开发人员的工作效率 原文: Making every developer more productive with Visual Stu ...