上一篇學習瞭如何使用RestTemplate發送http請求,可是講解比較簡單。因此這篇更加詳細的探究一下RestTemplate的使用。bash
首先咱們得知道RestTemplate是基於http請求的封裝,因此咱們就能夠根據http請求相關屬性來學習RestTemplate的使用。ide
1.請求鏈接時間和讀取時間的設置函數
在http請求中,有一個最大的鏈接時間和讀取時間的設置,那這個在RestTemplate中該怎麼設置呢?post
public RestTemplate(ClientHttpRequestFactory requestFactory) {
this();
setRequestFactory(requestFactory);
}
複製代碼
查看RestTemplate的構造函數,咱們能夠傳遞一個ClientHttpRequestFactory對象進去(經過set方法也能夠設置該屬性)。查看源碼,該對象的默認值是SimpleClientHttpRequestFactory。在SimpleClientHttpRequestFactory對象中,咱們就能夠設置connectTimeout和readTimeout兩個屬性了。學習
2.如何設置請求頭ui
在上一期使用getForObject方法的時候,咱們並無設置請求頭相關的屬性,若是須要設置該怎麼辦呢?this
這個時候能夠使用RestTemplate的exchange方法。編碼
<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
Class<T> responseType, Object... uriVariables) throws RestClientException;
複製代碼
exchange方法中第三個參數爲HttpEntity,在HttpEntity中咱們就能夠設置請求頭相關屬性了。url
另外,除了getForXXX方法外,像postForObject方法能夠直接將HttpEntity對象做爲request傳進去。RestTemplate會自動解析。spa
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.POST, requestCallback,responseExtractor, uriVariables);
}
public <T> RequestCallback httpEntityCallback(@Nullable Object requestBody, Type responseType) {
return new HttpEntityRequestCallback(requestBody, responseType);
}
public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) {
super(responseType);
//判斷request對象屬性是不是HttpEntity
if (requestBody instanceof HttpEntity) {
this.requestEntity = (HttpEntity<?>) requestBody;
}
else if (requestBody != null) {
this.requestEntity = new HttpEntity<>(requestBody);
}
else {
this.requestEntity = HttpEntity.EMPTY;
}
}
複製代碼
3.如何獲取響應頭及狀態碼信息
若是想要獲取響應頭相關的信息,能夠經過XXXForEntity相關的方法,獲取到ResponseEntity對象,經過ResponseEntity對象就能夠獲取到響應頭和響應狀態碼了。
可是在默認狀況下,若是響應的狀態碼不爲200的話,依然會拋出異常。由於默認的ResponseErrorHandler就是這麼幹的。
private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
String statusText = response.getStatusText();
HttpHeaders headers = response.getHeaders();
byte[] body = getResponseBody(response);
Charset charset = getCharset(response);
switch (statusCode.series()) {
case CLIENT_ERROR:
throw HttpClientErrorException.create(statusCode, statusText, headers, body, charset);
case SERVER_ERROR:
throw HttpServerErrorException.create(statusCode, statusText, headers, body, charset);
default:
throw new UnknownHttpStatusCodeException(statusCode.value(), statusText, headers, body, charset);
}
}
複製代碼
若是想自定義的話能夠本身實現一個ResponseErrorHandler,
RestTemplate template = new RestTemplate();
template.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
複製代碼
這樣的話即使是返回嗎不爲200,也不會拋出異常。方便咱們更加自定義的編碼。