写在前面
基本的微服务环境搭建,由provider提供服务,consumer通过Discovery先去eureka上获取provider的服务的地址,获取到地址之后再去调用相关的服务。在服务的调用过程中,使用了一个工具,叫做 RestTemplate ,RestTemplate 是由Spring提供的一个HTTP请求工具。在上文的案例中,开发者也可以不使用 RestTemplate, 使用JAVA自带的HttpUrlConnection 或者经典的网络访问框架 HttpClient 也可以完成上文的案例,只是在Spring项目中,使用 RestTemplate 显然更方便一些。
RestTemplate简介
RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。接下来我们就来看看这些操作方法的使用。
RestFul和控制器
概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
功能
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。
传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get
http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
RestTemplate
用法实战
在开始下面的案例之前,我们需要先创建一个工程,命名为 RestTemplate 。和上篇文章的项目结构一样,在 RestTemplate 中,我们也分别创建子项目 eureka 、provider 以及 consumer ,将 provider 和 consumer 分别注册到 eureka 上面去。
GET 请求
做好了准备工作,先来看使用 RestTemplate 发送 GET 请求。在 RestTemplate 中,和 GET 请求相关的方法有如下几个:
这里的方法一共有两类,getForEntity 和 getForObject,每一类有三个重载方法,下面我们分别予以介绍。
getForEntity
既然 RestTemplate 发送的是 HTTP 请求,那么在响应的数据中必然也有响应头,如果开发者需要获取响应头的话,那么就需要使用 getForEntity 来发送 HTTP 请求,此时返回的对象是一个 ResponseEntity 的实例。这个实例中包含了响应数据以及响应头。例如,在 provider 中提供一个 HelloController 接口,HelloController 接口中定义一个 sayHello 的方法,如下:
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello(String name) {
return "hello " + name + " !";
}
}
在 consumer 中定义一个 UseHelloController 的类,再定义一个 /hello 接口,在接口中调用 provider 提供的服务,如下:
@RestController
public class UseHelloController {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/hello")
public String hello(String name) {
List<ServiceInstance> list = discoveryClient.getInstances("provider");
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = "http://" + host + ":" + port + "/hello?name={1}";
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, name);
StringBuffer sb = new StringBuffer();
HttpStatus statusCode = responseEntity.getStatusCode();
String body = responseEntity.getBody();
sb.append("statusCode:")
.append(statusCode)
.append("</br>")
.append("body:")
.append(body)
.append("</br>");
HttpHeaders headers = responseEntity.getHeaders();
Set<String> keySet = headers.keySet();
for (String s : keySet) {
sb.append(s)
.append(":")
.append(headers.get(s))
.append("</br>");
}
return sb.toString();
}
}