Spring?Boot中調(diào)用外部接口的3種方式步驟
簡介
SpringBoot不僅繼承了Spring框架原有的優(yōu)秀特性,而且還通過簡化配置來進(jìn)一步簡化了Spring應(yīng)用的整個搭建和開發(fā)過程。在Spring-Boot項目開發(fā)中,存在著本模塊的代碼需要訪問外面模塊接口,或外部url鏈接的需求。
調(diào)用外部接口是指在應(yīng)用程序中與其他系統(tǒng)、服務(wù)或服務(wù)端點進(jìn)行通信,以獲取數(shù)據(jù)或執(zhí)行某些操作。這種通信可以通過 HTTP、HTTPS、SOAP、gRPC 等協(xié)議來實現(xiàn)。
調(diào)用外部接口通常涉及以下幾個步驟:
創(chuàng)建請求:根據(jù)接口文檔或約定,構(gòu)造請求的 URL、請求方法(如 GET、POST、PUT、DELETE 等)、請求頭、請求參數(shù)等信息。
發(fā)送請求:使用合適的客戶端工具(如 RestTemplate、WebClient、Feign 等)發(fā)送請求。這些工具提供了便捷的 API 來發(fā)送請求并將響應(yīng)結(jié)果返回給你。
處理響應(yīng):根據(jù)接口的響應(yīng)格式(如 JSON、XML 等),解析響應(yīng)內(nèi)容并提取需要的數(shù)據(jù)。你可以使用解析庫(如 Jackson、Gson、JAXB 等)來處理響應(yīng)內(nèi)容。
錯誤處理:在調(diào)用外部接口時,可能會遇到各種錯誤情況,如網(wǎng)絡(luò)連接失敗、接口返回錯誤碼等。你需要適當(dāng)處理這些錯誤情況,例如進(jìn)行重試、回退、記錄日志等操作。
在調(diào)用外部接口時,還需要注意以下事項:
接口安全性:如果接口需要身份驗證或授權(quán),你需要提供相應(yīng)的憑據(jù)(如 API 密鑰、令牌)或配置安全設(shè)置,以確保請求能夠被正確處理。
異步調(diào)用和并發(fā)性:如果你的應(yīng)用程序需要高并發(fā)或異步處理,你可以考慮使用基于消息隊列、異步任務(wù)或多線程等技術(shù),在后臺進(jìn)行接口調(diào)用,以提高系統(tǒng)的性能和可伸縮性。
監(jiān)控和日志記錄:對于重要的接口調(diào)用,建議設(shè)置適當(dāng)?shù)谋O(jiān)控和日志記錄,以便及時發(fā)現(xiàn)問題并進(jìn)行故障排查。
總之,調(diào)用外部接口是實現(xiàn)應(yīng)用程序與其他系統(tǒng)集成的重要方式,它能夠使你的應(yīng)用程序獲取到外部數(shù)據(jù),實現(xiàn)復(fù)雜的業(yè)務(wù)邏輯,并與其他系統(tǒng)進(jìn)行交互。選擇合適的調(diào)用方式和合理處理錯誤情況,能夠保證接口調(diào)用的可靠性和性能。
方案一:采用原生的httpClient請求
/** 1. 跨域請求工具類 */ public class HttpClientUtils { public static String doGet(String url, Map<String, String> param) { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 創(chuàng)建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 創(chuàng)建http GET請求 HttpGet httpGet = new HttpGet(uri); // 執(zhí)行請求 response = httpclient.execute(httpGet); // 判斷返回狀態(tài)是否為200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doGet(String url) { return doGet(url, null); } public static String doPost(String url, Map<String, String> param) { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 創(chuàng)建Http Post請求 HttpPost httpPost = new HttpPost(url); // 創(chuàng)建參數(shù)列表 if (param != null) { List<NameValuePair> paramList = new ArrayList<>(); for (String key : param.keySet()) { paramList.add(new BasicNameValuePair(key, param.get(key))); } // 模擬表單 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); httpPost.setEntity(entity); } // 執(zhí)行http請求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doPost(String url) { return doPost(url, null); } public static String doPostJson(String url, String json) { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 創(chuàng)建Http Post請求 HttpPost httpPost = new HttpPost(url); // 創(chuàng)建請求內(nèi)容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); // 執(zhí)行http請求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } }
方案二:采用原生的RestTemplate方法
RestTemplate 是 Spring 框架提供的用于訪問 RESTful 服務(wù)的客戶端工具類。它封裝了常見的 HTTP 請求操作,提供了簡單易用的 API,這里主要介紹Get和Post方法的使用。
Get請求
在 RestTemplate 中,getForEntity 方法有多個重載形式,可以根據(jù)需要選擇合適的方法進(jìn)行 GET 請求。提供了getForObject 、getForEntity兩種方式。
getForEntity
以下是 getForEntity
方法的三種形式:
1. getForEntity(String url, Class<T> responseType, Object... uriVariables); 2. getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables); 3. getForEntity(URI url, Class<T> responseType);
以下是對每個方法的說明和示例:
getForEntity(String url, Class<T> responseType, Object... uriVariables)
:
該方法提供了三個參數(shù),其中url為請求的地址,responseType為請求響應(yīng)body的包裝類型,urlVariables為url中的參數(shù)綁定- 此方法發(fā)送帶有路徑參數(shù)的 GET 請求,并以可變參數(shù)的形式傳遞路徑參數(shù)。
- 路徑參數(shù)將按順序替換 URL 中的占位符
{}
。
示例:
RestTemplate restTemplate = new RestTemplate(); ResponseEntity<User> response = restTemplate.getForEntity("http://example.com/api/users/{id}", User.class, 1); User user = response.getBody();
getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
:- 此方法發(fā)送帶有路徑參數(shù)的 GET 請求,并以鍵值對的形式傳遞路徑參數(shù)。
- 路徑參數(shù)通過鍵值對映射進(jìn)行替換。
示例:
RestTemplate restTemplate = new RestTemplate(); Map<String, Integer> uriVariables = new HashMap<>(); uriVariables.put("id", 1); ResponseEntity<User> response = restTemplate.getForEntity("http://example.com/api/users/{id}", User.class, uriVariables); User user = response.getBody();
getForEntity(URI url, Class<T> responseType)
:- 此方法發(fā)送 GET 請求,并通過
URI
對象來指定請求的完整 URL。
示例:
RestTemplate restTemplate = new RestTemplate(); URI url = new URI("http://example.com/api/users/1"); ResponseEntity<User> response = restTemplate.getForEntity(url, User.class); User user = response.getBody();
- 此方法發(fā)送 GET 請求,并通過
或者
RestTemplate restTemplate=new RestTemplate(); UriComponents uriComponents=UriComponentsBuilder.fromUriString("http://example.com/api/users/{id}") .build() .expand(1) .encode(); URI uri=uriComponents.toUri(); ResponseEntity<User> response = restTemplate.getForEntity(uri, User.class); User user = response.getBody();
getForObject
以下是 getForEntity
方法的三種形式:
1. getForObject(String url, Class<T> responseType, Object... uriVariables); 2. getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables); 3. getForObject(URI url, Class<T> responseType);
這段代碼是 RestTemplate
類中的 getForObject
方法的重寫實現(xiàn)。它用于發(fā)送 GET 請求,并返回一個指定類型的對象,而不是完整的響應(yīng)實體。
以下是對每個方法的說明和示例:
getForObject(String url, Class<T> responseType, Object... uriVariables)
:- 此方法發(fā)送帶有路徑參數(shù)的 GET 請求,并以可變參數(shù)的形式傳遞路徑參數(shù)。
- 路徑參數(shù)將按順序替換 URL 中的占位符
{}
。 - 最后,返回響應(yīng)體中轉(zhuǎn)換為指定類型的對象。
示例:
RestTemplate restTemplate = new RestTemplate(); User user = restTemplate.getForObject("http://example.com/api/users/{id}", User.class, 1);
getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
:- 此方法發(fā)送帶有路徑參數(shù)的 GET 請求,并以鍵值對的形式傳遞路徑參數(shù)。
- 路徑參數(shù)通過鍵值對映射進(jìn)行替換。
- 最后,返回響應(yīng)體中轉(zhuǎn)換為指定類型的對象。
示例:
RestTemplate restTemplate = new RestTemplate(); Map<String, Integer> uriVariables = new HashMap<>(); uriVariables.put("id", 1); User user = restTemplate.getForObject("http://example.com/api/users/{id}", User.class, uriVariables);
getForObject(URI url, Class<T> responseType)
:- 此方法發(fā)送 GET 請求,并通過
URI
對象來指定請求的完整 URL。 - 最后,返回響應(yīng)體中轉(zhuǎn)換為指定類型的對象。
示例:
RestTemplate restTemplate = new RestTemplate(); URI url = new URI("http://example.com/api/users/1"); User user = restTemplate.getForObject(url, User.class);
- 此方法發(fā)送 GET 請求,并通過
getForEntity和getForObject的聯(lián)系
getForObject
和 getForEntity
是 RestTemplate
類中用于發(fā)送 GET 請求并獲取響應(yīng)的兩個方法。它們在功能上有一些相似之處,但也有一些區(qū)別。
相同點:
- 都用于發(fā)送 GET 請求,并接收服務(wù)器返回的響應(yīng)。
- 都支持傳遞 URL、路徑參數(shù)和查詢參數(shù)來構(gòu)建完整的請求 URL。
- 都可以指定響應(yīng)的期望類型,并進(jìn)行自動的類型轉(zhuǎn)換。
區(qū)別:
getForObject
方法返回的是服務(wù)器響應(yīng)體中的內(nèi)容,并將其轉(zhuǎn)換為指定類型的對象。這意味著你直接獲取到了響應(yīng)體的內(nèi)容。getForEntity
方法返回的是一個ResponseEntity
對象,包含了完整的響應(yīng)信息,包括響應(yīng)頭、響應(yīng)狀態(tài)碼和響應(yīng)體。可以通過ResponseEntity
對象來獲取更多的響應(yīng)信息。
選擇使用哪個方法取決于你對響應(yīng)的需求:
- 如果你只需要獲得響應(yīng)體的內(nèi)容,并將其轉(zhuǎn)換為指定類型的對象,可以使用
getForObject
方法。這樣可以簡化代碼,僅關(guān)注響應(yīng)體的內(nèi)容。 - 如果你還需要獲取更多的響應(yīng)信息,例如響應(yīng)頭或狀態(tài)碼,或者需要對響應(yīng)進(jìn)行更細(xì)粒度的處理,那么可以使用
getForEntity
方法。它提供了更多的靈活性,可以訪問完整的響應(yīng)信息。
示例:
RestTemplate restTemplate = new RestTemplate(); // 使用 getForObject 方法 User user1 = restTemplate.getForObject("http://example.com/api/users/1", User.class); // 使用 getForEntity 方法 ResponseEntity<User> responseEntity = restTemplate.getForEntity("http://example.com/api/users/1", User.class); User user2 = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
總之,getForObject
和 getForEntity
都是用于發(fā)送 GET 請求并獲取響應(yīng)的方法,選擇使用哪個方法取決于你對響應(yīng)的需求。
Post請求
Post請求提供有postForEntity
、postForObject
和postForLocation
三種方式,其中每種方式都有三種方法,下面介紹postForEntity
的使用方法。
postForEntity
以下是 postForEntity
方法的三種形式:
1. postForEntity(String url, @Nullable Object request,Class<T> responseType, Object... uriVariables); 2. postForEntity(String url, @Nullable Object request,Class<T> responseType, Map<String, ?> uriVariables); 3. postForEntity(URI url, @Nullable Object request, Class<T> responseType);
這段代碼是 RestTemplate
類中的 postForEntity
方法的重寫實現(xiàn)。它用于發(fā)送 POST 請求,并返回一個包含完整響應(yīng)信息的 ResponseEntity
對象,而不僅僅是響應(yīng)體內(nèi)容。
下面是對每個重寫方法的詳細(xì)說明和示例:
postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
:- 此方法發(fā)送帶有路徑參數(shù)的 POST 請求,并以可變參數(shù)的形式傳遞路徑參數(shù)。
request
參數(shù)用于發(fā)送 POST 請求時的請求體內(nèi)容。- 最后,返回一個包含完整響應(yīng)信息的
ResponseEntity
對象,其中包括響應(yīng)頭、響應(yīng)狀態(tài)碼和響應(yīng)體。
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://example.com/api/users", userRequest, User.class, 1); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
:- 此方法發(fā)送帶有路徑參數(shù)的 POST 請求,并以鍵值對的形式傳遞路徑參數(shù)。
request
參數(shù)用于發(fā)送 POST 請求時的請求體內(nèi)容。- 最后,返回一個包含完整響應(yīng)信息的
ResponseEntity
對象。
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); Map<String, Integer> uriVariables = new HashMap<>(); uriVariables.put("id", 1); ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://example.com/api/users/{id}", userRequest, User.class, uriVariables); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
postForEntity(URI url, @Nullable Object request, Class<T> responseType)
:- 此方法發(fā)送 POST 請求,并通過
URI
對象來指定請求的完整 URL。 request
參數(shù)用于發(fā)送 POST 請求時的請求體內(nèi)容。- 最后,返回一個包含完整響應(yīng)信息的
ResponseEntity
對象。
示例:
RestTemplate restTemplate = new RestTemplate(); User userRequest = new User("John", "Doe"); URI url = new URI("http://example.com/api/users"); ResponseEntity<User> responseEntity = restTemplate.postForEntity(url, userRequest, User.class); User user = responseEntity.getBody(); HttpStatus statusCode = responseEntity.getStatusCode(); HttpHeaders headers = responseEntity.getHeaders();
- 此方法發(fā)送 POST 請求,并通過
注
:
request
和uriVariables
是用于構(gòu)造 POST 請求的兩個不同的參數(shù),它們在不同的作用域中起作用。
request
參數(shù):
request
參數(shù)表示發(fā)送 POST 請求時的請求體內(nèi)容。- 它可以是任意類型的對象,根據(jù)實際的請求需求來決定具體的類型。通常情況下,
request
參數(shù)會作為請求體的內(nèi)容進(jìn)行發(fā)送。- 如果你的 POST 請求不需要請求體,可以將
request
參數(shù)設(shè)置為null
。
uriVariables
參數(shù):
uriVariables
參數(shù)表示可選的路徑參數(shù),用于替換 URL 中的占位符。- 它是一個可變參數(shù),可以傳遞多個參數(shù)值。參數(shù)值的順序必須與 URL 中占位符的順序一致。
- 在發(fā)送 POST 請求時,將路徑參數(shù)與 URL 進(jìn)行替換,以獲得最終的請求 URL。
綜上所述,
request
和uriVariables
是兩個用于構(gòu)建 POST
請求不同參數(shù),分別代表請求體的內(nèi)容和路徑參數(shù)。需要根據(jù)具體的需求來使用它們。如果需要發(fā)送請求體,將內(nèi)容放在request
參數(shù)中;如果需要替換 URL 中的占位符,將參數(shù)值傳遞給uriVariables
參數(shù)。
postForObject
以下是 postForObject
方法的三種形式:
1. postForObject(String url, @Nullable Object request, Class<T> responseType,Object... uriVariables); 2. postForObject(String url, @Nullable Object request, Class<T> responseType,Map<String, ?> uriVariables); 3. postForObject(URI url, @Nullable Object request, Class<T> responseType);
這是 RestTemplate
類中關(guān)于 POST 請求的三個 postForObject
方法的實現(xiàn)。下面將詳細(xì)解釋每個方法及其示例用法:
postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
- 通過傳遞 URL 字符串、請求體對象、響應(yīng)類型和路徑參數(shù)數(shù)組,發(fā)送一個 POST 請求,并將響應(yīng)體轉(zhuǎn)換為指定的類型對象。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法使用占位符來替換 URL 中的路徑參數(shù)。
示例:
String url = "http://example.com/api/users/{id}"; User request = new User("John", "Doe"); Class<User> responseType = User.class; Object[] uriVariables = { 1 }; User user = restTemplate.postForObject(url, request, responseType, uriVariables);
postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
- 通過傳遞 URL 字符串、請求體對象、響應(yīng)類型和路徑參數(shù)映射,發(fā)送一個 POST 請求,并將響應(yīng)體轉(zhuǎn)換為指定的類型對象。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法使用鍵-值對來替換 URL 中的路徑參數(shù)。
示例:
String url = "http://example.com/api/users/{id}"; User request = new User("John", "Doe"); Class<User> responseType = User.class; Map<String, Object> uriVariables = new HashMap<>(); uriVariables.put("id", 1); User user = restTemplate.postForObject(url, request, responseType, uriVariables);
postForObject(URI url, @Nullable Object request, Class<T> responseType)
- 通過傳遞完整的 URI 對象、請求體對象和響應(yīng)類型,發(fā)送一個 POST 請求,并將響應(yīng)體轉(zhuǎn)換為指定的類型對象。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法不支持替換 URL 中的路徑參數(shù)。
示例:
URI url = new URI("http://example.com/api/users"); User request = new User("John", "Doe"); Class<User> responseType = User.class; User user = restTemplate.postForObject(url, request, responseType);
postForLocation
以下是 postForLocation
方法的三種形式:
1. postForLocation(String url, @Nullable Object request, Object... uriVariables); 2. postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables); 3. postForLocation(URI url, @Nullable Object request);
這是 RestTemplate
類中關(guān)于 POST 請求并獲取 Location 頭部信息的三個 postForLocation
方法的實現(xiàn)。下面將詳細(xì)解釋每個方法及其示例用法:
postForLocation(String url, @Nullable Object request, Object... uriVariables)
- 通過傳遞 URL 字符串、請求體對象和路徑參數(shù)數(shù)組,發(fā)送一個 POST 請求,并返回響應(yīng)頭部中的 Location 信息,作為一個 URI 對象返回。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法使用占位符來替換 URL 中的路徑參數(shù)。
示例:
String url = "http://example.com/api/users"; User request = new User("John", "Doe"); Object[] uriVariables = { 1 }; URI location = restTemplate.postForLocation(url, request, uriVariables);
postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables)
- 通過傳遞 URL 字符串、請求體對象和路徑參數(shù)映射,發(fā)送一個 POST 請求,并返回響應(yīng)頭部中的 Location 信息,作為一個 URI 對象返回。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法使用鍵-值對來替換 URL 中的路徑參數(shù)。
示例:
String url = "http://example.com/api/users"; User request = new User("John", "Doe"); Map<String, Object> uriVariables = new HashMap<>(); uriVariables.put("id", 1); URI location = restTemplate.postForLocation(url, request, uriVariables);
postForLocation(URI url, @Nullable Object request)
- 通過傳遞完整的 URI 對象和請求體對象,發(fā)送一個 POST 請求,并返回響應(yīng)頭部中的 Location 信息,作為一個 URI 對象返回。
- 如果不需要發(fā)送請求體,可以將
request
參數(shù)設(shè)置為null
。 - 此方法不支持替換 URL 中的路徑參數(shù)。
示例:
URI url = new URI("http://example.com/api/users"); User request = new User("John", "Doe"); URI location = restTemplate.postForLocation(url, request);
postForEntity、postForObject和postForLocation的聯(lián)系
postForEntity
、postForObject
和 postForLocation
都是 RestTemplate
類中用于發(fā)送 POST 請求的方法,它們之間存在一些聯(lián)系和區(qū)別。
聯(lián)系:
- 參數(shù):這三個方法都接受相同的參數(shù):請求的 URL、請求體對象以及可選的路徑參數(shù)或路徑參數(shù)映射。
- HTTP 請求方法:這三個方法都使用 POST 方法發(fā)送請求。
區(qū)別:
返回值類型:
postForEntity
返回一個ResponseEntity
對象,包含完整的響應(yīng)信息,如響應(yīng)狀態(tài)碼、頭部信息和響應(yīng)體。postForObject
返回一個指定的響應(yīng)體類型的對象,僅包含響應(yīng)體內(nèi)容。postForLocation
僅返回響應(yīng)頭部中的 Location 信息作為一個 URI 對象。
使用場景:
postForEntity
和postForObject
適用于需要處理完整響應(yīng)信息的情況,可以獲取響應(yīng)狀態(tài)碼、頭部信息和響應(yīng)體,并根據(jù)需要進(jìn)行處理。postForLocation
適用于只關(guān)注響應(yīng)頭部中的 Location 信息的情況,常用于資源的創(chuàng)建和重定向場景。
總結(jié):
這三個方法都用于發(fā)送 POST 請求,根據(jù)需要返回不同的信息。如果需要完整的響應(yīng)信息,包括響應(yīng)狀態(tài)碼、頭部信息和響應(yīng)體,可以使用 postForEntity
;如果只需要響應(yīng)體內(nèi)容,可以使用 postForObject
;如果僅關(guān)注響應(yīng)頭部中的 Location 信息,可以使用 postForLocation
。
方案三:使用Feign進(jìn)行消費
Feign 是一個聲明式的、基于接口的 HTTP 客戶端,它簡化了使用 Spring Cloud 進(jìn)行遠(yuǎn)程服務(wù)調(diào)用的過程。通過 Feign,可以以聲明式的方式定義和調(diào)用遠(yuǎn)程服務(wù)接口,而無需手動編寫實現(xiàn)代碼。
在使用 Feign 進(jìn)行消費時,需要完成以下幾個步驟:
創(chuàng)建 Feign 客戶端接口:定義一個接口,使用
@FeignClient
注解指定服務(wù)名稱和服務(wù)地址。該接口中定義了需要調(diào)用的遠(yuǎn)程服務(wù)接口的方法及其相關(guān)信息,例如 HTTP 方法、URL 路徑、請求參數(shù)和請求體等。啟用 Feign 客戶端:在 Spring Boot 應(yīng)用程序的啟動類或配置類上添加
@EnableFeignClients
注解,以啟用 Feign 客戶端功能。使用 Feign 客戶端接口:通過注入 Feign 客戶端接口對象,即可使用該接口中定義的方法進(jìn)行遠(yuǎn)程服務(wù)調(diào)用。Feign 會根據(jù)接口定義自動實現(xiàn)具體的調(diào)用邏輯,并處理請求和響應(yīng)。
Feign 的工作原理如下:
- 根據(jù) Feign 客戶端接口的定義,在運行時動態(tài)生成具體的代理類。
- 當(dāng)調(diào)用 Feign 客戶端接口的方法時,代理類會負(fù)責(zé)根據(jù)方法的元數(shù)據(jù)(如 HTTP 方法、URL 路徑、請求參數(shù)等)組裝出一個完整的 HTTP 請求。
- 發(fā)送構(gòu)建好的 HTTP 請求到目標(biāo)服務(wù)端,進(jìn)行遠(yuǎn)程調(diào)用。
- 目標(biāo)服務(wù)端響應(yīng)請求后,將響應(yīng)結(jié)果返回給 Feign 客戶端。
- Feign 客戶端根據(jù)定義的返回類型,將響應(yīng)結(jié)果轉(zhuǎn)換為相應(yīng)的對象或數(shù)據(jù),并返回給調(diào)用方。
Feign 還具備以下特性:
- 內(nèi)置負(fù)載均衡:Feign 集成了 Ribbon 負(fù)載均衡器,可以在多個服務(wù)提供方之間自動進(jìn)行負(fù)載均衡,提高系統(tǒng)的可用性和性能。
- 自動服務(wù)發(fā)現(xiàn):Feign 可以與服務(wù)注冊中心(如 Eureka)集成,自動從服務(wù)注冊中心獲取服務(wù)地址,避免硬編碼服務(wù)地址。
- 可插拔的編解碼器:Feign 支持多種序列化和反序列化方式,如 JSON、XML 等,可以根據(jù)需求選擇適合的編解碼器。
- 客戶端日志記錄:Feign 具備日志記錄功能,可以方便地打印出請求和響應(yīng)的詳細(xì)信息,便于排查問題和監(jiān)控性能。
總而言之,F(xiàn)eign 提供了一種簡單且優(yōu)雅的方式來定義和調(diào)用遠(yuǎn)程服務(wù)接口,它屏蔽了底層的 HTTP 請求細(xì)節(jié),使得遠(yuǎn)程服務(wù)調(diào)用更加便捷和靈活。同時,通過與 Spring Cloud 的集成,F(xiàn)eign 還可以享受到負(fù)載均衡、服務(wù)發(fā)現(xiàn)等分布式系統(tǒng)支持。
具體實現(xiàn)
使用 Feign 進(jìn)行消費時,需要進(jìn)行以下步驟:
添加 Feign 依賴:在項目的構(gòu)建文件中添加 Feign 相關(guān)的依賴,例如 Maven 的 pom.xml 文件:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
啟用 Feign 客戶端:在 Spring Boot 應(yīng)用程序的啟動類或配置類上添加
@EnableFeignClients
注解,以啟用 Feign 客戶端功能。@SpringBootApplication @EnableFeignClients @ComponentScan(basePackages = {"com.definesys.mpaas", "com.xdap.*" ,"com.xdap.*"}) public class MobilecardApplication { public static void main(String[] args) { SpringApplication.run(MobilecardApplication.class, args); } }
創(chuàng)建 Feign 客戶端接口:創(chuàng)建一個接口,使用
@FeignClient
注解指定服務(wù)名稱和服務(wù)地址。定義需要調(diào)用的 HTTP 方法、URL 路徑、請求參數(shù)和請求體等信息。例如://此處name需要設(shè)置不為空,url需要在.properties中設(shè)置,也可直接寫url @FeignClient(name = "example-service",url = "${outSide.url}") public interface ExampleClient { @GetMapping("/api/users/{id}") User getUser(@PathVariable("id") Long id); @PostMapping("/api/users") User createUser(@RequestBody User user); }
調(diào)用 Feign 客戶端接口:通過注入 Feign 客戶端接口對象,即可使用其定義的方法進(jìn)行遠(yuǎn)程服務(wù)調(diào)用。例如:
@RestController public class ExampleController { private final ExampleClient exampleClient; public ExampleController(ExampleClient exampleClient) { this.exampleClient = exampleClient; } @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { return exampleClient.getUser(id); } @PostMapping("/users") public User createUser(@RequestBody User user) { return exampleClient.createUser(user); } }
配置 Feign 客戶端:可以通過配置文件來配置 Feign 客戶端的行為,例如設(shè)置連接超時時間、請求重試等。在
application.properties
或application.yml
文件中添加相關(guān)配置。
以上是使用 Feign 進(jìn)行消費的基本步驟。Feign 可以根據(jù)接口定義自動生成符合服務(wù)提供方 API 規(guī)范的客戶端實現(xiàn),并且內(nèi)部集成了負(fù)載均衡和服務(wù)發(fā)現(xiàn)等功能,簡化了遠(yuǎn)程服務(wù)調(diào)用的過程。
添加Header解決方法
在使用 Feign 進(jìn)行遠(yuǎn)程服務(wù)調(diào)用時,可以通過添加 Header 來傳遞額外的請求信息。下面介紹兩種常見的方式來添加 Header。
使用
@RequestHeader
注解:在 Feign 客戶端接口的方法參數(shù)上使用@RequestHeader
注解,指定要添加的 Header 的名稱和值。例如:@GetMapping("/api/users/{id}") User getUser(@PathVariable("id") Long id, @RequestHeader("Authorization") String token);
在調(diào)用該方法時,將會在請求頭中添加一個名為 “Authorization” 的 Header,其值為傳入的
token
參數(shù)的值。使用
Interceptor
攔截器:可以自定義一個 Interceptor 實現(xiàn)RequestInterceptor
接口,在apply()
方法中添加需要的 Header。例如:public class CustomHeaderInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header("Authorization", "Bearer your_token"); } }
然后,在 Feign 客戶端接口上使用
@FeignClient
注解的configuration
屬性指定使用的攔截器類。例如:@FeignClient(name = "example-service", url = "http://example.com", configuration = CustomHeaderInterceptor.class) public interface ExampleClient { // ... }
這樣,在每次使用該 Feign 客戶端接口進(jìn)行遠(yuǎn)程調(diào)用時,都會在請求頭中自動添加上述定義的 Header。
以上是兩種常見的添加 Header 的方法。根據(jù)實際需求和場景,可以選擇適合的方式來添加自定義的 Header 信息。
Spring Boot 調(diào)用外部接口的三種方式的聯(lián)系
Spring Boot 調(diào)用外部接口的方式有多種,常見的有以下三種方式:RestTemplate、Feign 和 WebClient。它們之間存在一些聯(lián)系和區(qū)別。
RestTemplate:
- RestTemplate 是 Spring Framework 提供的傳統(tǒng)的 HTTP 客戶端工具,在 Spring Boot 中也得到了支持。
- 通過 RestTemplate,可以發(fā)送 HTTP 請求并接收響應(yīng),支持同步調(diào)用。
- RestTemplate 具有廣泛的功能,可以處理各種請求和響應(yīng)內(nèi)容,支持自定義編解碼、攔截器等功能。
- RestTemplate 使用起來相對簡單,直接調(diào)用其方法即可,適用于簡單的接口調(diào)用場景。
Feign:
- Feign 是基于接口的聲明式的 HTTP 客戶端,是 Spring Cloud 提供的組件之一。
- Feign 在 Spring Boot 中通過
@FeignClient
注解定義和使用。 - 通過 Feign,可以以聲明式的方式定義遠(yuǎn)程服務(wù)接口,并且 Feign 會自動代理實現(xiàn)具體的調(diào)用邏輯,無需手動編寫實現(xiàn)代碼。
- Feign 集成了 Ribbon 負(fù)載均衡器和 Eureka 服務(wù)注冊中心,可以自動進(jìn)行負(fù)載均衡和服務(wù)發(fā)現(xiàn)。
- Feign 更加高級抽象和靈活,適用于需要更多功能和集成分布式系統(tǒng)環(huán)境的場景。
WebClient:
- WebClient 是 Spring WebFlux 提供的非阻塞的 HTTP 客戶端。
- WebClient 基于 Reactor 響應(yīng)式編程模型,能夠在異步非阻塞的情況下處理大量并發(fā)請求。
- WebClient 支持使用函數(shù)式編程風(fēng)格來定義請求和處理響應(yīng),可以使用 Mono 和 Flux 處理異步結(jié)果。
- WebClient 適用于高性能、高并發(fā)的場景,并且在 Spring Boot 2.x 中是推薦的方式。
這三種方式在實際使用中有一些聯(lián)系和區(qū)別:
- RestTemplate 是傳統(tǒng)的 HTTP 客戶端,使用較為簡單,適用于簡單的接口調(diào)用場景。
- Feign 是基于接口的聲明式客戶端,集成了負(fù)載均衡和服務(wù)發(fā)現(xiàn)等功能,適用于分布式系統(tǒng)下的服務(wù)調(diào)用。
- WebClient 是非阻塞的 HTTP 客戶端,支持異步、響應(yīng)式編程模型,適用于高并發(fā)、高性能的場景。
選擇使用哪種方式需要根據(jù)具體的需求和場景來決定。在 Spring Boot 中,可以根據(jù)項目的特點和要求,靈活選擇適合的方式進(jìn)行外部接口調(diào)用。
總結(jié)
到此這篇關(guān)于Spring Boot中調(diào)用外部接口的3種方式步驟的文章就介紹到這了,更多相關(guān)Spring Boot調(diào)用外部接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA Project窗口的一些設(shè)置詳解
這篇文章主要介紹了IntelliJ IDEA Project窗口的一些設(shè)置詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08springboot攔截器過濾token,并返回結(jié)果及異常處理操作
這篇文章主要介紹了springboot攔截器過濾token,并返回結(jié)果及異常處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09windows系統(tǒng)配置Java開發(fā)環(huán)境變量
這篇文章主要介紹了windows系統(tǒng)配置Java開發(fā)環(huán)境變量,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-12-12Java實現(xiàn)刪除排序鏈表中的重復(fù)元素的方法
這篇文章主要介紹了Java實現(xiàn)刪除排序鏈表中的重復(fù)元素的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Java使用itextpdf找出PDF中文字的坐標(biāo)
這篇文章主要為大家詳細(xì)介紹了Java如果使用itextpdf找出PDF中文字的坐標(biāo),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-01-01java編程實現(xiàn)楊輝三角兩種輸出結(jié)果實例代碼
這篇文章主要介紹了java編程實現(xiàn)楊輝三角兩種輸出結(jié)果實例代碼,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12