RestTemplate

chenxin
21
2024-11-19

什么是RestTemplate

RestTemplate官网

RestTemplate 是 Spring 提供的一种用于 发送 HTTP 请求并接收响应 的工具类,广泛应用于微服务架构中服务间的通信。
它可以轻松地实现对外部 RESTful 服务的访问,并支持多种 HTTP 方法如 GET、POST、PUT 和 DELETE 等。

典型应用场景
假设我们有两个微服务:

服务提供者(Service A):提供资源或业务逻辑。
服务消费者(Service B):需要通过 HTTP 请求调用 Service A。
在 Service B 中,我们可以使用 RestTemplate 来发送 HTTP 请求到 Service A,并获取结果。

RestTemplate配置

RestTemplate 可以通过其无参构造函数使用默认配置初始化,也可以通过 Spring IoC 容器管理并注入到需要使用的地方。

package com.atguigu.cloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

RestTemplate的常见方法

RestTemplate支持多种http方法,例如get和post方法。

get

getForObject 和 getForEntity 是 RestTemplate 用于发送 GET 请求的两种常见方法

getForObject

getForObject
发送 GET 请求并直接返回响应体中数据反序列化后的对象。
使用场景:只关心响应体的内容。

    @Resource
    private RestTemplate restTemplate;
    private static final String PaymentSrv_URL="http://localhost:8001";
    @GetMapping("/consumer/pay/get/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id){
        return restTemplate.getForObject(PaymentSrv_URL+"/pay/get/"+id, ResultData.class);
    }

getForEntity

getForEntity
返回 ResponseEntity 对象,包含了响应体、状态码和响应头等额外信息。
使用场景:需要处理 HTTP 响应的状态码或头信息时。

    @Resource
    private RestTemplate restTemplate;
    private static final String PaymentSrv_URL="http://localhost:8001";
    @GetMapping("/consumer/pay/get/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id){
        return restTemplate.getForObject(PaymentSrv_URL+"/pay/get/"+id, ResultData.class).getBody();
    }

post

postForObject和postForEntity是常见的发送post请求的方法

postForObject

postForObject
发送 POST 请求并直接返回响应体中数据反序列化后的对象。
使用场景:只关心响应体内容。

url为请求url,request为post请求所携带参数,reponseType为响应类型

    @Resource
    private RestTemplate restTemplate;
    private static final String PaymentSrv_URL="http://localhost:8001";
    @GetMapping("/consumer/pay/add")
    public ResultData addOrder(PayDTO payDTO){
      return restTemplate.postForObject(PaymentSrv_URL+"/pay/add",payDTO, ResultData.class);
    }

getForEntity

postForEntity
返回 ResponseEntity 对象,包含了响应体、状态码和响应头等额外信息。
使用场景:需要处理 HTTP 响应的状态码或头信息时。

    @Resource
    private RestTemplate restTemplate;
    private static final String PaymentSrv_URL="http://localhost:8001";
    @GetMapping("/consumer/pay/add")
    public ResultData addOrder(PayDTO payDTO){
        return restTemplate.postForEntity(PaymentSrv_URL+"/pay/add",payDTO, ResultData.class).getBody();
    }

entity vs object

可以看到,无论是get和post请求,都分为entity和object两种。
对于object,返回对象为响应体中数据转化成的对象,基本上可以理解为Json。
而对于entity,返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等。

常见注意事项

异常处理

如果调用的服务返回非 2xx 的状态码,RestTemplate 会抛出 HttpClientErrorException 或 HttpServerErrorException。
可以通过全局异常处理器捕获异常,或使用 try-catch 来处理。

服务之间的负载均衡

在分布式系统中,可以结合 Ribbon、Feign 等组件实现服务的负载均衡。
例如:使用 @LoadBalanced 注解为 RestTemplate 添加负载均衡能力:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

替代方案
从 Spring 5 开始,官方推荐使用 WebClient 替代 RestTemplate,因为 RestTemplate 基于阻塞式 I/O,性能相对较低。
WebClient 基于非阻塞式 I/O,适合高并发场景。

动物装饰