【Spring Cloud系列】- RestTemplate使用详解(上)

简介: 【Spring Cloud系列】- RestTemplate使用详解

一、初识RestTemplate

RestTemplate是Spring框架提供用于调用Rest接口的一个应用,它简化了与http服务通信方式。RestTemplate统一Restfull调用的标准,封装HTTP链接,只要需提供URL及返回值类型即可完成调用。相比传统的HttpClient与Okhttp,RestTemplate是一种优雅,简洁调用RESTfull服务的方式。

RestTemplate默认依赖JDK提供Http连接的能力(HttpURLConnection),如果有需要的话也可以通过SetRequestFactory方法替换为如:Apache HttpComponents、Netty或OKHttp等其他HTTP库。

二、RestTemplate调用流程详解:

2.1. 实例化RestTemplate

RestTemplate template=new RestTemplate();

2.2. 通过RestTemplate内部通过调用 doExecute 方法,首先就是获取 ClientHttpRequest

RestTemplate中doExecute核心代码

  • 通过ClientHttpRequestFactory工厂生产一个ClientHttpRequest
ClientHttpRequest request;
try {
  request = createRequest(url, method);
 }catch (IOException ex) {
    ResourceAccessException exception = createResourceAccessException(url, method, ex);
  throw exception;
}
  • 封装了请求头和请求体,使用了HttpMessageConverter
if (requestCallback != null) {
    requestCallback.doWithRequest(request);
}
  • 执行ClientHttpRequest中execute 方法请求
response = request.execute();
  • ClientHttpRequest中handleResponse方法处理Http响应结果,执行失败并抛出ResponseErrorHandler异常
handleResponse(url, method, response);
  • handleResponse方法代码
ResponseErrorHandler errorHandler = getErrorHandler();
boolean hasError = errorHandler.hasError(response);
if (logger.isDebugEnabled()) {
    try {
        HttpStatusCode statusCode = response.getStatusCode();
        logger.debug("Response " + statusCode);
    }catch (IOException ex) {
        logger.debug("Failed to obtain response status code", ex);
    }
}
if (hasError) {
  errorHandler.handleError(url, method, response);
}

2.3. RestTemplate 实现了抽象类 HttpAccessor ,可以调用父类(HttpAccessor)的 createRequest方法

在HttpAccessor中

private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
public ClientHttpRequestFactory getRequestFactory() {
   return this.requestFactory;
}
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
  ClientHttpRequest request = getRequestFactory().createRequest(url, method);
  initialize(request);
  if (logger.isDebugEnabled()) {
   logger.debug("HTTP " + method.name() + " " + url);
  }
  return request;
}

2.4. SimpleClientHttpRequestFactory 实现了接口ClientHttpRequestFactory,同时实现createRequest方法

在RestTemplate可以设置是否使用缓存流,默认设置:bufferRequestBody =true,缺点是当发送大量数据时,比如put/post的保存和修改,那么可能内存消耗严重。所以这时候可以设置 RestTemplate.setBufferRequestBody(false);

即使用 SimpleStreamingClientHttpRequest 来实现

@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
    //创建java.net.HttpURLConnection 
  HttpURLConnection connection = openConnection(uri.toURL(), this.proxy);
    //创建connection属性,同时设置了setDoInput
  prepareConnection(connection, httpMethod.name());
  if (this.bufferRequestBody) {
    return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming);
  }
  else {
    return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming);
  }
}

2.5. openConnection 即打开连接,而是 prepareConnection 各种连接准备,针对请求者

openConnection源码:

protected HttpURLConnection openConnection(URL url, @Nullable Proxy proxy) throws IOException {
  URLConnection urlConnection = (proxy != null ? url.openConnection(proxy) : url.openConnection());
  if (!(urlConnection instanceof HttpURLConnection)) {
    throw new IllegalStateException(
          "HttpURLConnection required for [" + url + "] but got: " + urlConnection);
  }
  return (HttpURLConnection) urlConnection;
}

prepareConnection方法:

protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
  //设置连接超时时间:connectTimeout
  if (this.connectTimeout >= 0) {
    connection.setConnectTimeout(this.connectTimeout);
  }
  //设置读超时时间:readTimeout
  if (this.readTimeout >= 0) {
    connection.setReadTimeout(this.readTimeout);
  }
  Boolean mayWrite =("POST".equals(httpMethod) || 
                     "PUT".equals(httpMethod) ||
           "PATCH".equals(httpMethod) || 
                     "DELETE".equals(httpMethod));
  //设置URL允许输入:connection.setDoInput(true);//默认true
  //URL连接可用于输入和/或输出。 如果您打算使用URL连接进行输入,请将DoInput标志设置为true;
  //否则,设置为false。 默认值是true。
  //HttpUrlConnection中方法setDoInput(true);以后就可以使用conn.getInputStream().read();
  connection.setDoInput(true);
  connection.setInstanceFollowRedirects("GET".equals(httpMethod));
  //URL连接可用于输入和/或输出。 如果您打算将URL连接用于输出,请将DoOutput标志设置为true,
  //如果不是,则为false 默认值是false。  
  //如get请求,用不到conn.getOutputStream(),因为参数直接追加在地址后面,因此默认是false
  //post、put、patch、delete请求会将setDoOutput设置为true
  //设置setDoOutput(true);以后就可以使用conn.getOutputStream().write()
  connection.setDoOutput(mayWrite); 
  connection.setRequestMethod(httpMethod);
}


目录
相关文章
|
1天前
|
监控 安全 Java
Spring cloud原理详解
Spring cloud原理详解
10 0
|
5天前
|
消息中间件 负载均衡 Java
【Spring Cloud 初探幽】
【Spring Cloud 初探幽】
13 1
|
7天前
|
Java 开发者 微服务
Spring Cloud原理详解
【5月更文挑战第4天】Spring Cloud是Spring生态系统中的微服务框架,包含配置管理、服务发现、断路器、API网关等工具,简化分布式系统开发。核心组件如Eureka(服务发现)、Config Server(配置中心)、Ribbon(负载均衡)、Hystrix(断路器)、Zuul(API网关)等。本文讨论了Spring Cloud的基本概念、核心组件、常见问题及解决策略,并提供代码示例,帮助开发者更好地理解和实践微服务架构。此外,还涵盖了服务通信方式、安全性、性能优化、自动化部署、服务网格和无服务器架构的融合等话题,揭示了微服务架构的未来趋势。
31 6
|
11天前
|
JSON Java Apache
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
Spring Cloud Feign 使用Apache的HTTP Client替换Feign原生httpclient
|
11天前
|
负载均衡 Java 开发者
Spring Cloud:一文读懂其原理与架构
Spring Cloud 是一套微服务解决方案,它整合了Netflix公司的多个开源框架,简化了分布式系统开发。Spring Cloud 提供了服务注册与发现、配置中心、消息总线、负载均衡、熔断机制等工具,让开发者可以快速地构建一些常见的微服务架构。
|
13天前
|
消息中间件 Java RocketMQ
Spring Cloud RocketMQ:构建可靠消息驱动的微服务架构
【4月更文挑战第28天】消息队列在微服务架构中扮演着至关重要的角色,能够实现服务之间的解耦、异步通信以及数据分发。Spring Cloud RocketMQ作为Apache RocketMQ的Spring Cloud集成,为微服务架构提供了可靠的消息传输机制。
28 1
|
13天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo: 微服务通信的高效解决方案
【4月更文挑战第28天】在微服务架构的发展中,服务间的高效通信至关重要。Spring Cloud Dubbo 提供了一种基于 RPC 的通信方式,使得服务间的调用就像本地方法调用一样简单。本篇博客将探讨 Spring Cloud Dubbo 的核心概念,并通过具体实例展示其在项目中的实战应用。
15 2
|
13天前
|
监控 Java Sentinel
Spring Cloud Sentinel:概念与实战应用
【4月更文挑战第28天】在分布式微服务架构中,确保系统的稳定性和可靠性至关重要。Spring Cloud Sentinel 为微服务提供流量控制、熔断降级和系统负载保护,有效预防服务雪崩。本篇博客深入探讨 Spring Cloud Sentinel 的核心概念,并通过实际案例展示其在项目中的应用。
23 0
|
13天前
|
Cloud Native Java Nacos
Spring Cloud Nacos:概念与实战应用
【4月更文挑战第28天】Spring Cloud Nacos 是一个基于 Spring Cloud 构建的服务发现和配置管理工具,适用于微服务架构。Nacos 提供了动态服务发现、服务配置、服务元数据及流量管理等功能,帮助开发者构建云原生应用。
20 0