在微服務架構模式中,多個小型服務可以協同工作以提供一個特定的業務功能。這些服務之間可以通過REST API進行通信。要使用REST API,我們需要HTTP客戶端,例如RestTemplate。RestTemplate是Spring框架提供的一個珍貴的HTTP客戶端。它使開發人員能夠使用HTTP請求進行遠程調用。
一、RestTemplate的概述
RestTemplate是在Spring框架中提供的一個用於訪問Rest服務的模板工具集,其實就是對HttpClient的封裝。它提供了對HTTP請求生命周期的封裝,使得開發者能夠更方便地通過HTTP請求來調用Rest服務。
要使用RestTemplate,我們需要在Spring應用程序上下文中定義RestTemplate bean。可以使用如下語句快速創建RestTemplate:
RestTemplate restTemplate = new RestTemplate();
Spring提供了多種實現方式,包括Apache HttpClient以及Java原生URLConnection。它可以處理GET、POST、PUT、DELETE和其他HTTP請求方法,並且可以將服務端返回的JSON、XML和其他格式的數據進行轉換。
二、實現RestTemplate基本使用
下面我們演示如何使用RestTemplate的GET請求方法。RestTemplate的getForObject()方法是RESTful API最好的工具。通過簡單的代碼行,我們就能夠獲取以JSON、XML等格式的數據。
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/student/get/{id}";
Map<String, String> uriParams = new HashMap<>();
uriParams.put("id", "1");
Student student = restTemplate.getForObject(url, Student.class, uriParams);
System.out.println(student);
以上代碼中使用了getForObject方法,其中參數說明如下:
- url:目標URL,支持佔位符URI。佔位符以「{」和「}」包裝,並且必須與url變量Map uriVariables和var-args參數(如果有)的鍵匹配。
- responseType:返回類型,其可以是一個正常的對象類型,例如Student,或將響應映射到集合類型,例如List<Student>
- uriVariables:佔位符替換數組
除了GET請求方法,在RestTemplate中還有POST、PUT等常見的HTTP請求方法。這裡就不詳細展開了。
三、擴展RestTemplate的使用
1. 添加HTTP頭信息
在發送HTTP請求時添加HTTP頭信息,可以通過RestTemplate的Header請求頭來實現:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
在以上示例中,我們將添加accept Http頭來請求響應。在類HttpHeaders的實例化中,設置accept值為MediaType.APPLICATION_JSON,表示在響應中請求JSON數據。
2. 錯誤處理
在遠程服務調用時,總會存在網絡連接失敗等異常情況,我們需要捕獲這些異常,並對其進行處理。
RestTemplate提供了一個特殊的類RestClientException,用於捕獲所有的異常。例如,我們可以通過以下方式在RestTemplate調用失敗時捕獲異常:
try {
ResponseEntity<String> response = restTemplate.getForEntity(URL, String.class);
} catch (RestClientException e) {
e.printStackTrace();
}
3. 異步調用RestTemplate
RestTemplate的請求是同步的,但是在高並發場景下,使用異步方式調用可以提高系統的性能。
Java8之前使用Callable和Future,Java8之後可以使用CompletableFuture。下面是Java8之前的代碼:
RestTemplate restTemplate = new RestTemplate();
String url = "localhost:8080/index";
Callable<Map> task = () -> {
ResponseEntity<Map> exchange = restTemplate.exchange(url, HttpMethod.GET, request, Map.class);
return exchange.getBody();
};
FutureTask<Map> futureTask = new FutureTask<Map>(task);
new Thread(futureTask).start();
Map result = futureTask.get();
使用CompletableFuture的代碼如下所示:
RestTemplate restTemplate = new RestTemplate();
String url = "localhost:8080/index";
CompletableFuture<String> future = CompletableFuture.supplyAsync(() ->
restTemplate.getForObject(url, String.class));
String result = future.get();
4. 自定義HttpMessageConverter
RestTemplate通過使用HttpMessageConverter將Http請求和響應轉換為對象。默認情況下,HttpClient支持JSON和XML。如果您的服務端將數據提供為Jackson、Gson、XML或您自己的格式,您可以編寫自定義消息轉換器。
下面是一個自定義的消息轉換器:
public class MappingJackson2CalendarHttpMessageConverter extends MappingJackson2HttpMessageConverter {
public MappingJackson2CalendarHttpMessageConverter() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_JSON);
setSupportedMediaTypes(mediaTypes);
}
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
ObjectMapper mapper = getObjectMapper();
ObjectWriter writer = mapper.writerWithView(Views.Public.class);
writer.writeValue(outputMessage.getBody(), object);
}
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
ObjectMapper mapper = getObjectMapper();
return mapper.readValue(inputMessage.getBody(), getJavaType(clazz));
}
}
上述代碼演示了繼承MappingJackson2HttpMessageConverter並支持MediaType為application/json的文件格式。自定義的消息轉換器MappingJackson2CalendarHttpMessageConverter允許您通過重寫readInternal和writeInternal方法將請求和響應轉換為所需的數據格式。
四、總結
RestTemplate是一個非常強大的HTTP客戶端,可以用於與第三方REST服務進行通信,獲取JSON/XML等數據,並對其進行處理。本文介紹了RestTemplate的基本用法、擴展用法、以及自定義實現HttpMessageConverter的用法。希望可以幫助到大家。
原創文章,作者:RLVLV,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/371572.html