持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
RestTemplate是Spring提供的一种更优雅的调用RESTful服务的方式,它简化了与http服务的通信方式,统一了RESTful的标准,封装了HTTP链接,还可以自定义RestTemplate所需的模式。
类依赖关系图
- HttpAccessor是一个抽象类,它抽象的是一个http访问器的概念。
- RestOperations是一个接口,抽象的是restful风格的操作方法。
- RestTemplate则是聚合了两者,既有http访问器的基础能力,又在这个基础之上构建了restful风格。
组成部分
ClientHttpRequestFactory:ClientHttpRequest工厂类,通过ClientHttpRequestInterceptor自定义 ClientHttpRequest:代表客户端HTTP请求的抽象 ResponseErrorHandler:异常处理 ClientHttpRequestInterceptor:请求拦截器 HttpMessageConverter:对象转换器
contentType与messageConverter之间的关系
| 类名 | 支持的JavaType | 支持的MediaType |
|---|---|---|
| ByteArrayHttpMessageConverter | byte[] | application/octet-stream, / |
| StringHttpMessageConverter | String | text/plain, / |
| ResourceHttpMessageConverter | Resource | / |
| SourceHttpMessageConverter | Source | application/xml, text/xml, application/*+xml |
| AllEncompassingFormHttpMessageConverter | Map<K, List<?>> | application/x-www-form-urlencoded, multipart/form-data |
| MappingJackson2HttpMessageConverter | Object | application/json, application/*+json |
| Jaxb2RootElementHttpMessageConverter | Object | application/xml, text/xml, application/*+xml |
| JavaSerializationConverter | Serializable | x-java-serialization;charset=UTF-8 |
| FastJsonHttpMessageConverter | Object | / |
核心逻辑
- new RestTemplate():添加HttpMessageConverter;初始化UriTemplateHandler
- restTemplate.getForObject:调用RestTemplate.doExecute方法
- createRequest(url, method):工厂类创建HTTP请求对象
- request.execute():执行请求,调用InterceptingClientHttpRequest.executeInternal
- requestExecution.execute:执行拦截器处理,最后执行HTTP请求
- delegate.execute:执行请求,获取响应
- handleResponse(url, method, response):处理ClientHttpResponse响应对象
源码分析
org.springframework.web.client.RestTemplate.java
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
ClientHttpResponse response = null;
try {
// 创建HTTP请求对象,调用InterceptingClientHttpRequest.executeInternal
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) {
throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + ex.getMessage(), ex);
} finally {
response.close();
}
}
org.springframework.http.client.InterceptingClientHttpRequest.java
@Override
protected final ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
InterceptingRequestExecution requestExecution = new InterceptingRequestExecution();
return requestExecution.execute(this, bufferedOutput);
}
private class InterceptingRequestExecution implements ClientHttpRequestExecution {
@Override
public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {
// 执行拦截器
if (this.iterator.hasNext()) {
ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();
return nextInterceptor.intercept(request, body, this);
}
else {
HttpMethod method = request.getMethod();
// 工厂类创建HTTP请求对象
ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), method);
// 执行请求
return delegate.execute();
}
}
}
使用
HTTP方法说明
| 方法 | 描述 |
|---|---|
| delete() | 在特定的URL上对资源执行HTTP DELETE操作 |
| getForEntity() | 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象 |
| getForObject() | 发送一个HTTP GET请求,返回的请求体将映射为一个对象 |
| postForEntity() | POST 数据到一个URL,返回包含一个对象的ResponseEntity |
| postForObject() | POST 数据到一个URL,返回根据响应体匹配形成的对象 |
| put() | PUT 资源到特定的URL |
| ... | ... |
- 配置
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory simleClientHttpRequestFactory) {
RestTemplate restTemplate = new RestTemplate();
reqFactory.setConnectTimeout(restTemplateConnectionTimeout);
reqFactory.setReadTimeout(restTemplateReadTimeout);
//配置自定义的message转换器
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
messageConverters.add(new CustomMappingJackson2HttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
//配置自定义的interceptor拦截器
List<ClientHttpRequestInterceptor> interceptors=new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new HeadClientHttpRequestInterceptor());
interceptors.add(new TrackLogClientHttpRequestInterceptor());
restTemplate.setInterceptors(interceptors);
//配置自定义的异常处理
restTemplate.setErrorHandler(new CustomResponseErrorHandler());
restTemplate.setRequestFactory(simleClientHttpRequestFactory);
return restTemplate;
}
}
- 使用
@RestController
public class Demo1Controller {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/user/list")
public List<User> userList() {
return restTemplate.getForObject("http://unififi-demo2-service/user/list", List.class);
}
}