Spring RestTemplate介绍

上篇文件介绍Eureka服务的文章中,我们介绍到consumer从Eureka中通过LoadBalancerClient获取到服务端地址信息后通过RestTemplate来远程调用服务的场景,本文来具体介绍下RestTemplate的使用

RestTemplate

  SpringRestTemplate是Spring 提供的用于访问 Rest 服务的客端, RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如Android或者第三方服务商都是使用RestTemplate 请求 restful服务

1.环境搭建

  为了演示RestTemplate的使用,我们创建两个SpringBoot项目,一个provider作为server端,一个consumer作为服务调用方法

在这里插入图片描述

2.API方法介绍

API说明
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
delete()在特定的URL上对资源执行HTTP DELETE操作
exchange()在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
execute()在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象

3.具体使用

  我们通过常用的http协议的四种请求方式来看下效果

3.1 无参请求

  我们先来看下服务端请求方法不需要接收参数,

getForEntity

  通过getForEntity来实现
服务端

 /**
  * 无参,返回字符串
  * @return
  */
 @GetMapping("/server1")
 public String server1String(){
     System.out.println("服务端被访问了...");
     return "success";
 }

调用

/**
 * RestTemplate 访问 provider的第一个服务 server1
 */
@Test
public void contextLoads() {
    String url = "http://localhost:8080/server1";
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
    // 获取响应的状态
    HttpStatus statusCode = entity.getStatusCode();
    // 获取响应的header信息
    HttpHeaders headers = entity.getHeaders();
    // 获取响应的body信息
    String msg = entity.getBody();
    System.out.println(statusCode);
    System.out.println(headers);
    System.out.println(msg);
}

输出结果

在这里插入图片描述
说明:

1.getForEntity()方法执行返回的类型是ResponseEntity<T>,ResponseEntity<T>是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等,在输出结果中我们能够看到
2.getForEntity()的参数中第一个是请求地址,第二个是T对应的类型

getForObject

  getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject

/**
 * getForObject 访问
 */
@Test
public void contextLoadsObject() {
    String url = "http://localhost:8080/server1";
    RestTemplate restTemplate = new RestTemplate();
    // 直接返回的就是我们需要的结果,但是获取不到对应的响应状态等信息
    String msg = restTemplate.getForObject(url,String.class);
    System.out.println(msg);
}

3.2 有参请求

服务端方法需要接收调用者传递的参数

 /**
   * 有参,基本数据类型 返回字符串
   * @return
   */
  @RequestMapping("/server2")
  public String server2String(Integer id,String userName){
      System.out.println("服务端被访问了..."+id+" "+userName);
      return "success--参数得到了";
  }

  /**
   * 有参,基本数据类型 返回字符串
   * @return
   */
  @RequestMapping("/server3")
  public String server3String(User user){
      System.out.println("服务端被访问了..."+user);
      return "success--参数得到了";
  }

getForEntity

调用者可以通过两种方式调用
第一种方式通过数字占位符,最后是一个可变长度的参数,来一一替换前面的占位符

/**
* 请求服务并且传递参数
*     基本数据类型
*/
@Test
public void testServer2(){
	// 参数在链接地址后
   String url = "http://localhost:8080/server2?id={1}&userName={2}";
   RestTemplate restTemplate = new RestTemplate();
   ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class,5,"bobo");
   System.out.println(entity.getBody());
}

第二种就是使用name={name}这种形式,最后一个参数是一个map,map的key即为前边占位符的名字,map的value为参数值

/**
 * 请求服务并且传递参数
 *     基本数据类型
 */
@Test
public void testServer3(){
    String url = "http://localhost:8080/server2?id={id}&userName={userName}";
    Map<String,Object> map = new HashMap<>();
    map.put("id",6);
    map.put("userName","波波烤鸭");
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class,map);
    System.out.println(entity.getBody());
}
  •  

postForEntity

  如果是post方式提交请求传递参数我们可以这样使用,如下
服务端:注意要加@RequestBody注解

/**
 * 有参,基本数据类型 返回字符串
 * @return
 */
@RequestMapping("/server3")
public String server3String(@RequestBody  User user){
    System.out.println("服务端被访问了..."+user);
    return "success--参数得到了";
}

客户端

/**
 * postForEntity(url,user,String.class)
 *  url:请求地址
 *  user:请求提交的数据
 *  String.class 接收返回数据的类型
 */
@Test
public void contextLoadsObject1() {
    String url = "http://localhost:8080/server3";
    RestTemplate restTemplate = new RestTemplate();
    User user = new User(1,"bobo","中国");
    // 直接返回的就是我们需要的结果,但是获取不到对应的响应状态等信息
    String msg = restTemplate.postForEntity(url,user,String.class).getBody();
    System.out.println(msg);
}

3.3 返回自己类型

  服务端返回的我们自定义类型的数据

 /**
  * 返回自定义对象
  * @return
  */
 @RequestMapping("/server4")
 public User server4Object(){
     System.out.println("服务端被访问了...");
     return new User(2,"李四","深圳");
 }

客户端:

/**
 * 返回类型为自定义类型
 */
@Test
public void testServer5(){
    String url = "http://localhost:8080/server4";
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<User> entity = restTemplate.getForEntity(url, User.class);
    System.out.println(entity.getBody());
}

使用getForEntity和getForObject及postForEntity和postForObject都差不多,注意接收的类型即可。

3.4 返回的list带泛型的场景

  此处我们需要使用到exchange方法,特定如下

  1. 允许调用者指定HTTP请求的方法(GET,POST,PUT等)
  2. 可以在请求中增加body以及头信息,其内容通过参‘HttpEntity<?>requestEntity’描述
  3. exchange支持‘含参数的类型’(即泛型类)作为返回类型,该特性通过‘ParameterizedTypeReferenceresponseType’描述
/**
 * 返回 集合带泛型
 * @return
 */
@RequestMapping("/server5")
public List<User> server5List(){
    System.out.println("服务端被访问了...");
    return Arrays.asList(new User(2,"李四1","深圳")
                        ,new User(3,"李四2","深圳")
                        ,new User(4,"李四3","深圳"));
}

客户端调用

/**
 * 返回类型为List带泛型
 */
@Test
public void testServer6(){
    String url = "http://localhost:8080/server5";
    RestTemplate restTemplate = new RestTemplate();
    // 注意后面有一对{} ParameterizedTypeReference本身是抽象类
    ParameterizedTypeReference<List<User>> pr = new ParameterizedTypeReference<List<User>>() {};
    ResponseEntity<List<User>> exchange = restTemplate.exchange(url, HttpMethod.GET, null, pr);
    System.out.println(exchange.getBody());
}

在这里插入图片描述

好了~RestTemplate的基本使用我们就介绍到此处

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值