概述
RestTemplate与httpClient类似,都是java中可以模拟http请求的封装。httpClient的使用,已经在另一篇文章中有所论述,但是RestTemplate比httpClient更优雅,它是spring中的一个封装功能。
RestTemplate也是java中的模板类。采用的设计模式中的模板模式。
源码解析
RestTemplate继承InterceptingHttpAccessor抽象类,实现RestOperation接口
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations
在RestOperations定义了基本的Rest操作集合。RestTemplate实现了这个接口
public interface RestOperations {
// GET
<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> T getForObject(URI url, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
// HEAD
HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientException;
HttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientException;
HttpHeaders headForHeaders(URI url) throws RestClientException;
// POST
URI postForLocation(String url, Object request, Object... uriVariables) throws RestClientException;
URI postForLocation(String url, Object request, Map<String, ?> uriVariables) throws RestClientException;
URI postForLocation(URI url, Object request) throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException;
<T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException;
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
// PUT
void put(String url, Object request, Object... uriVariables) throws RestClientException;
void put(String url, Object request, Map<String, ?> uriVariables) throws RestClientException;
void put(URI url, Object request) throws RestClientException;
// PATCH
<T> T patchForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException;
<T> T patchForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException;
<T> T patchForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
// DELETE
void delete(String url, Object... uriVariables) throws RestClientException;
void delete(String url, Map<String, ?> uriVariables) throws RestClientException;
void delete(URI url) throws RestClientException;
// OPTIONS
Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientException;
Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RestClientException;
Set<HttpMethod> optionsForAllow(URI url) throws RestClientException;
// exchange
<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> exchange(String url,HttpMethod method, HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType) throws RestClientException;
<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
throws RestClientException;
// general execution
<T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException;
<T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables) throws RestClientException;
<T> T execute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor) throws RestClientException;
}
PostForObject与PostForEntity的区别在于前者请求返回就是响应体,后者返回的是响应行,响应头,响应体。
这里也有一个基础的http访问类HttpAccessor,里面主要是一个工厂方法,用来构造HttpRequestFactory
public abstract class HttpAccessor {
protected final Log logger = LogFactory.getLog(getClass());
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
Assert.notNull(requestFactory, "ClientHttpRequestFactory must not be null");
this.requestFactory = requestFactory;
}
public ClientHttpRequestFactory getRequestFactory() {
return this.requestFactory;
}
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
ClientHttpRequest request = getRequestFactory().createRequest(url, method);
if (logger.isDebugEnabled()) {
logger.debug("Created " + method.name() + " request for \"" + url + "\"");
}
return request;
}
}
springboot对RestTemplate的集成
首先添加配置;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
}
不然在service中的autowired会注入不进去
再设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
请求行,请求头,请求体分装成 一个Entity
HttpEntity<String> entity = new HttpEntity<>(JSONObject.toJSONString(dto),headers );
接下来就调用出
ResponseEntity<String> r = restTemplate.exchange(ADD_URL, HttpMethod.POST, entity, String.class);
那就可以请求到结果了。
总结
整个restTemplate比httpClient使用更加优雅,分装的更好
restTemplate是org.springframework.web.client包中的类,是spring提供的类。
httpclient是org.apache.http.client包中的类,是apache提供的类。