所有文章

https://www.cnblogs.com/lay2017/p/11740855.html

正文

上一篇文章中,我们创建了一个ClientHttpRequest的实例。本文将继续阅读ClientHttpRequest的执行逻辑。

再次回顾一下restTemplate核心逻辑的代码

protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException { ClientHttpResponse response = null;
try {
// 生成请求
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
// 设置header
requestCallback.doWithRequest(request);
}
// 执行请求,获取响应
response = request.execute();
// 处理响应
handleResponse(url, method, response);
// 获取响应体对象
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
// ... 抛出异常
}
finally {
if (response != null) {
// 关闭响应流
response.close();
}
}
}

ClientHttpRequest的默认实现类是SimpleBufferingClientHttpRequest,我们先看看它的继承关系

可以看到,ClientHttpRequest直接被AbstractClientHttpRequest继承,所以我们先从AbstractClientHttpRequest实现的execute方法开始

跟进execute方法

@Override
public final ClientHttpResponse execute() throws IOException {
assertNotExecuted();
ClientHttpResponse result = executeInternal(this.headers);
this.executed = true;
return result;
}

execute方法前置校验executed这个flag,executeInternal执行完后打了个true的标记。所以一个ClientHttpRequest将只能被执行一次。

继续跟进executeInternal方法,executeInternal方法由AbstractBufferingClientHttpRequest实现

@Override
protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException {
byte[] bytes = this.bufferedOutput.toByteArray();
if (headers.getContentLength() < 0) {
headers.setContentLength(bytes.length);
}
ClientHttpResponse result = executeInternal(headers, bytes);
this.bufferedOutput = new ByteArrayOutputStream(0);
return result;
}

核心逻辑在executeInternal(headers, bytes)里,继续跟进它

executeInternal(headers, bytes)由SimpleBufferingClientHttpRequest实现

@Override
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
addHeaders(this.connection, headers);
// JDK <1.8 doesn't support getOutputStream with HTTP DELETE
if (getMethod() == HttpMethod.DELETE && bufferedOutput.length == 0) {
this.connection.setDoOutput(false);
}
if (this.connection.getDoOutput() && this.outputStreaming) {
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
}
this.connection.connect();
if (this.connection.getDoOutput()) {
// 写到输出流上
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
}
else {
// Immediately trigger the request in a no-output scenario as well
this.connection.getResponseCode();
}
// 响应一个ClientHttpResponse对象
return new SimpleClientHttpResponse(this.connection);
}

如果开启了输出流,那么FileCopyUtils.copy方法将会把缓冲数据写入到输出流里面。

注意:FileCopyUtils.copy方法在写入完毕后会关闭输出流,所以不需要外部显式关闭。我们看copy方法

public static void copy(byte[] in, OutputStream out) throws IOException {
Assert.notNull(in, "No input byte array specified");
Assert.notNull(out, "No OutputStream specified"); try {
out.write(in);
}
finally {
try {
out.close();
}
catch (IOException ex) {
}
}
}

executerInternal(headers, bytes)方法最后会响应一个SimpleClientHttpResponse实例对象,单纯地包装了Connection对象。

SimpleClientHttpResponse(HttpURLConnection connection) {
this.connection = connection;
}

显然,后续的处理就是从ClientHttpResponse中读取输入流,然后格式化成一个响应体,最后回收资源。下一篇内容讲述这个

总结

执行ClientHttpRequest逻辑其实就是与服务端创建Connection连接(如果有需要写入数据则写入到输出流),整体还是比较简单的。

最新文章

  1. Python更换国内源实现快速PIP安装
  2. asp.net 读取一个文本文件,并输出到网页显示 通过 一般处理程序实现
  3. Leetcode 200. number of Islands
  4. IntelliJ IDEA 常用设置讲解1
  5. qq互联登陆开发流程
  6. jsonp使用规范
  7. iOS开发总结-UIWebView 集成 浏览器
  8. TREEVIEW节点拖拽
  9. eclipse中的两种Jre 及 Jre与Jdk的区别
  10. Centos程序最小化后,窗口标签都消失找不到窗口的问题
  11. 【Learning】多项式乘法与快速傅里叶变换(FFT)
  12. Java的URL类(一)
  13. IntelliJ常用快捷键及配置
  14. (0)HomeAssistant 教程
  15. Kafka消费时报错:Producer connection to xxx:9092 unsuccessful
  16. [NOIP2018]摆渡车
  17. 编译Caffe出错,解决方案记录
  18. 概率分布之间的推导关系 | Univariate Distribution Relationships
  19. 专注做好一件事(转) focus---这个世界上最成功的人,他们在某一领域获得成功之后,可通过经营杠杆进入任何他们想要涉足的领域。而这都得依赖于他们曾极致的专注在做好一件事情上。
  20. Template Method 模板方法 MD

热门文章

  1. C#-片段-插入片段:Visual C#
  2. SVG动画示例
  3. 【分类算法】决策树(Decision Tree)
  4. 在过滤器中获取在web.xml配置的初始化参数
  5. 阿里fastjson工具类
  6. git帮助和小结
  7. Java环境中,word文档转PDF直接打开浏览而非下载
  8. iOS中处理json解析出现的null,nil的解决办法
  9. SQL Server 2008 R2如何使用正则表达式搜索
  10. 多林环境中的ADFS