转载自: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

  1. 无参数的 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; }
  1. 有参数的 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;
}
  1. 有参数的 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

    1. 无参数的 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; }
  1. 有参数的 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;
}
  1. 有参数的 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

  1. 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 中的信息:

    1. 有参数的 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 操作的更多相关文章

  1. linux iostat命令详解 磁盘操作监控工具

    Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视. 它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况. ...

  2. Web服务器之Nginx详解(操作部分)

    大纲 一.前言 二.Nginx 安装与配置 三.Nginx 配置文件详解 四.Nginx 命令参数 五.配置Nginx提供Web服务 六.配置Nginx的虚拟主机 七.配置Nginx的用户认证 八.配 ...

  3. 【Tools】VMware虚拟机三种网络模式详解和操作

    目录 00. 目录 01. VMware虚拟机三种网络模式 02. Bridged(桥接模式) 03. NAT(地址转换模式) 04. Host-Only(仅主机模式) 00. 目录 @ 参考:htt ...

  4. 详解文件操作(ifstream、ofstream、fstream)[转]

    C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...

  5. 详解PHP操作Memcache缓存技术提高响应速度的方法

    本文转载http://blog.csdn.net/zhihua_w  不错的博客,仅供本人学习之用 一般来说,如果并发量不大的情况,使不使用缓存技术并没有什么影响,但如果高并发的情况,使用缓存技术就显 ...

  6. Hbase Shell命令详解+API操作

    HBase Shell 操作 3.1 基本操作1.进入 HBase 客户端命令行,在hbase-2.1.3目录下 bin/hbase shell 2.查看帮助命令 hbase(main):001:0& ...

  7. Reg命令使用详解 批处理操作注册表必备

    首先要说明:编辑注册表不当可能会严重损坏您的系统.在更改注册表之前,应备份计算机上任何有价值的数据 只有在别无选择的情况下,才直接编辑注册表.注册表编辑器会忽略标准的安全措施,从而使得这些设置会降低性 ...

  8. Linux setenforce命令详解[SeLinux操作]

    SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统. 关闭SELinux 临时生效: 命令临时 ...

  9. 009-Hadoop Hive sql语法详解4-DQL 操作:数据查询SQL-select、join、union、udtf

    一.基本的Select 操作 语法SELECT [ALL | DISTINCT] select_expr, select_expr, ...FROM table_reference[WHERE whe ...

随机推荐

  1. Python:Day07 作业

    三级菜单: 自己做的代码: china = { '江苏':{ '南京':{ '江宁':{}, '白下':{}, '栖霞':{}, '江淮':{}, '浦口':{} }, '宿迁':{ '宿城区':{} ...

  2. 【移动端】单位em相关资料

    https://www.cnblogs.com/koubazhuanshu/p/6985331.html https://www.w3cplus.com/css/px-to-em 不建议使用 作者:s ...

  3. JUnit5 快速指南

    JUnit5 快速指南 version: junit5 1. 安装 2. JUnit 注解 3. 编写单元测试 3.1. 基本的单元测试类和方法 3.2. 定制测试类和方法的显示名称 3.3. 断言( ...

  4. 01-Jenkins-Master节点安装

    Jenkins安装前需要JDK8,下载最新版本的Jenkins LTS 2.150.防止下载缓慢可以通过清华源进行下载. [root@node1 ~]# wget https://mirrors.tu ...

  5. odoo 基于SQL View视图的model类

    在做odoo的过程中,会涉及到多表的查询, 尤其是做报表的时候这种情况更甚,这样下来会做很多的关联,不是很方便.odoo提供了一种机制,即基于视图的model类.代码地址在这里. 具体过程如下: 1. ...

  6. CSS实现树形结构 + js加载数据

    看到一款树形结构,比较喜欢它的样式,就参照它的外观自己做了一个,练习一下CSS. 做出来的效果如下: li { position: relative; padding: 5px 0; margin:0 ...

  7. 开源工具 DotnetRSA 快速生成和转换RSA秘钥

    一.简介 DotnetRSA 是一个利用 .NET Core 2.1 开发的 .NET Global Tool,是可以想npm全局安装一样,安装在你的系统中,只需敲一行命令便可以快速生成RSA加密算法 ...

  8. zookeeper-操作与应用场景-《每日五分钟搞定大数据》

    Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基 ...

  9. Python从菜鸟到高手(18):类与方法的私有化

    1. 创建自己的类 学习面向对象的第一步,就是创建一个类.因为类是面向对象的基石.Python类和其他编程语言(Java.C#等)的类差不多,也需要使用class关键字.下面通过一个实际的例子来看一下 ...

  10. C# 实现实时网速

    前言 最近参加了一个项目,所以写博客的时间就少了,项目中有一个功能就是在窗体上显示实时网速,用了半天的时间写了出来,想想今天时间蛮充足,就把它分享到博客上吧. 项目展示 项目核心代码: private ...