所有文章
https://www.cnblogs.com/lay2017/p/11740855.html
正文
上一篇文章中,我们构造了一个RestTemplate的Bean实例对象。本文将主要了解一下RestTemplate执行请求的核心逻辑。
先写一个简单的get请求示例代码
@Autowired private RestTemplate restTemplate; public String getData() { return restTemplate.getForEntity("http://www.baidu.com", String.class).getBody(); }
示例代码通过restTemplate的getForEntity方法发出请求,并返回一个ResponseEntity,getBody方法从ResponseEntity中获取响应体。
getForEntity方法是RestOperations接口定义的,RestTemplate做了相应的实现。让我们打开RestOperations看看该接口的定义
/** * get请求 * @param url 请求的urL地址 * @param responseType 响应对象的类型 * @param uriVariables uri变量 * @return 响应体 **/ <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
该接口简单的定义了访问什么资源,响应的是什么类型的数据
再跟进RestTemplate实现类,看看getForEntity的具体实现
@Override public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { // 请求回调 RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); // 响应体抽取 ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); // 核心执行逻辑 return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables)); }
可以看到,execute里包含了核心的执行逻辑。跟进该方法
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException { // uri处理 URI expanded = getUriTemplateHandler().expand(url, uriVariables); // 核心逻辑 return doExecute(expanded, method, requestCallback, responseExtractor); }
execute方法先生成了一个URI,然后委托给了doExecute来处理
跟进doExecute方法
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(); } } }
doExecute方法的逻辑代码展示了核心的请求响应逻辑。主要包含三块内容:
1)createRequest创建请求对象
2)request.execute()执行该请求,与服务端交互获取响应数据
3)handleResponse()方法处理响应,responseExtractor生成ResponseEntity响应对象
总结
我们看到,restTemplate的核心逻辑很好的遵循了请求响应模型。doExecute的方法包含了核心逻辑代码。
后续,我们将拆开其中的几个核心方法看看实现细节。