6、SpringCloud之Rest请求模板类
服务消费端去调用服务提供者的服务的时候,使用了RestTemplate。RestTemplate通过getForEntity方法发起请求调用服务端的数据,并通过@LoadBanlaced注解开启客户端负载均衡。
RestTemplate中常见请求方法的使用
GET 查
POST 增
PUT 改
DELETE 删
通过注解指定通过什么请求方式进行访问,如下:
@Autowired
private RestTemplate restTemplate;
// 通过@GetMapping注解就能够指定请求方式
@GetMapping("/web/hello")
public String hello(){
// Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();
}
RestTemplate 的 GET请求
Get请求可以有两种方式
第一种:getForEntity
该方法返回一个ResponseEntity
@Autowired
private RestTemplate restTemplate;
// @RequestMapping("/web/hello")
@GetMapping("/web/hello")
public String hello(){
//这里泛型之所以是String类型,是因为方法的第二参数指定了返回类型为String
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class);
int statusCodeValue = responseEntity.getStatusCodeValue();
HttpStatus statusCode = responseEntity.getStatusCode();
HttpHeaders headers = responseEntity.getHeaders();
String body = responseEntity.getBody();
System.out.println(statusCodeValue);
System.out.println(statusCode);
System.out.println(headers);
System.out.println(body);
// Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();
}
getForEntity方法第二个参数String.class 表示希望返回的body类型是String类型,如果希望返回一个对象,也是可以的,比如User对象;
给两个服务提供者端,提供实体类User
package com.example.springcloud.model;
public class User {
private Integer id;
private String name;
private String phone;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", phone='" + phone + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
并提供返回值为User的Controller方法
@RequestMapping("/service/user")
public User user(){
User user = new User();
user.setId(12);
user.setName("小黑");
user.setPhone("12345678978");
return user;
}
此时,由于服务调用者调用此方法返回数据将数据绑定到实体类User对象上,所以也需要创建User实体类;
当多个工程都需要同一个实体类时,可以选择构建父工程,用Maven进行模块化管理。
此外,服务调用端需要提供一个方法来调用服务提供端
@GetMapping("/web/user")
public String user(){
//这里泛型之所以是String类型,是因为方法的第二参数指定了返回类型为String
ResponseEntity<User> responseEntity = restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/user", User.class);
int statusCodeValue = responseEntity.getStatusCodeValue();
HttpStatus statusCode = responseEntity.getStatusCode();
HttpHeaders headers = responseEntity.getHeaders();
User body = responseEntity.getBody();
System.out.println(statusCodeValue);
System.out.println(statusCode);
System.out.println(headers);
System.out.println(body.getId()+","+body.getName()+","+body.getPhone());
// Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();
}
完成之后,启动服务注册中心工程,服务提供端,以及服务调用端进行测试
getForEntity 常用的重载方法
服务提供端 接收请求参数并进行返回
//通过@RequestParam进行参数绑定
@RequestMapping("/service/user")
public User getUser(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("phone") String phone){
System.out.println("服务提供者1");
User user = new User();
user.setId(id);
user.setName(name);
user.setPhone(phone);
return user;
}
服务消费端
下面以两种方式。通过数组和Map对url请求地址进行参数绑定
/**
* getForEntity()以数组的方式将参数绑定到URL参数中
* 通过 {下标} 占位符的方式进行绑定
* 返回数据的封装类型为User类型(返回值类型也可以是String)
* @return
*/
@GetMapping("/web/ArrayParamGetUser")
public String getUser(){
String[] strArray = {"105", "小红", "12345678989"};
// Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={1}&name={2}&phone={3}", User.class, strArray).getBody().toString();
}
/**
* getForEntity()以数组的方式将参数绑定到URL参数中
* 通过 {key} 占位符的方式进行绑定
* 返回值类型是String类型
* @return
*/
@GetMapping("/web/MapParamgetUser")
public String getUser2(){
Map<String, Object> paramMap = new ConcurrentHashMap<>();
paramMap.put("id",1);
paramMap.put("name","小诚");
paramMap.put("phone", "1546879166");
// Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", String.class, paramMap).getBody();
}
第二种:getForObject()
共同点
getForObject()方法是getForEntity()方法的封装;
getForEntity方法重载的,getForObject方法也有,使用方式也类似;
不同点
getForEntity方法可以拿到返回的数据,同时也可以拿到头部信息状态码等;
getForObject方法只能用于获取返回的body信息;
/**
* getForEntity()以Map的方式将参数绑定到URL参数中
* @return
*/
@GetMapping("/web/getUserByGetForObject")
public String getUserByGetForObject(){
Map<String, Object> paramMap = new ConcurrentHashMap<>();
paramMap.put("id",1);
paramMap.put("name","小诚");
paramMap.put("phone", "1546879166");
//用请求模板类RestTemplate的getForObject方法,传入一个Map对象通过{key}占位符绑定url请求参数,返回值类型为String类型
String body = restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", String.class, paramMap);
System.out.println(body);
String[] strArray = {"105", "小红", "12345678989"};
//用请求模板类RestTemplate的getForObject方法,传入一个Map对象通过{index}占位符绑定url请求参数,返回值类型为User对象类型
User user2 = restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", User.class, strArray);
System.out.println(user2);
return restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class);
}
RestTemplate 的 POST 请求
POST 与 Get 请求 非常类似
restTemplate.postForObject()
restTemplate.postForEntity()
restTemplate.postForLocation()
服务提供者添加支持Post请求的方法
// @RequestMapping(value="/service/addUser", method = RequestMethod.POST)
@PostMapping("/service/addUser")
public User addUser(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("phone") String phone){
System.out.println("服务提供者1");
User user = new User();
user.setId(id);
user.setName(name);
user.setPhone(phone);
//将user对象插入数据库(暂时省略)
return user;
}
服务消费者添加调用Post请求的方法
/**
* 消费者调用 -addUser方法
* @return
*/
@RequestMapping("/web/addUser")
public String addUser(){
//注意post请求传递参数只能用MultiValueMap
MultiValueMap<String, Object> dataMap = new LinkedMultiValueMap();
dataMap.add("id",1);
dataMap.add("name","小诚");
dataMap.add("phone", "1546879166");
ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/addUser", dataMap, User.class);
System.out.println(responseEntity.getStatusCodeValue());
System.out.println(responseEntity.getStatusCode());
System.out.println(responseEntity.getHeaders());
System.out.println(responseEntity.getBody());
User user = restTemplate.postForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/addUser", dataMap, User.class);
System.out.println(user);
return "请求成功";
}
RestTemplate 的 PUT 请求
服务提供者添加支持Put请求的方法
// @RequestMapping(value="/service/updateUser", method = RequestMethod.PUT)
@PutMapping("/service/updateUser")
public User updateUser(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("phone") String phone){
User user = new User();
user.setId(id);
user.setName(name);
user.setPhone(phone);
System.out.println("服务提供者1");
System.out.println(user);
//将user对象插入数据库(暂时省略)
return user;
}
服务消费者添加调用Put请求的方法
/**
* 消费者调用 -updateUser方法
* @return
*/
@RequestMapping("/web/updateUser")
public String updateUser(){
MultiValueMap<String, Object> dataMap = new LinkedMultiValueMap();
dataMap.add("id",1);
dataMap.add("name","小诚");
dataMap.add("phone", "1546879166");
//put请求没有返回值
restTemplate.put("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/updateUser",dataMap);
return "请求成功";
}
RestTemplate 的 DELETE 请求
服务提供者添加支持Put请求的方法
// @RequestMapping(value="/service/addUser", method = RequestMethod.PUT)
@DeleteMapping("/service/deleteUser")
public User deleteUser(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("phone") String phone){
User user = new User();
user.setId(id);
user.setName(name);
user.setPhone(phone);
System.out.println("服务提供者2");
System.out.println(user);
//将user对象插入数据库(暂时省略)
return user;
}
服务消费者添加调用Delete请求的方法
/**
* 消费者调用 -deleteUser方法
* @return
*/
@RequestMapping("/web/deleteUser")
public String deleteUser(){
String[] strArray = {"105", "小红", "12345678989"};
restTemplate.delete("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/deleteUser?id={0}&name={1}&phone={2}", strArray);
Map<String, Object> paramMap = new ConcurrentHashMap<>();
paramMap.put("id",1);
paramMap.put("name","小诚");
paramMap.put("phone", "1546879166");
restTemplate.delete("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/deleteUser?id={id}&name={name}&phone={phone}", paramMap);
return "请求成功";
}
总结:
Get 和 Delete 写法相似
Post 和 Put 写法相似