在我們的業務流程之中不一定都會是自己模塊查詢自己模塊的信息,有些時候就需要去結合其他模塊的信息來進行一些查詢完成相應的業務流程,但是在SpringCloud每個模塊都相對獨立,數據庫也有數據隔離。所以當我們需要其他微服務模塊的信息的時候,就需要跨模塊調用發起網絡請求。
就像電商項目中,購物車模塊就不得不需要像商品模塊發起查詢請求。購物車業務中需要查詢商品信息,但商品信息查詢的邏輯全部遷移到了item-service
服務,導致我們無法查詢。
最終結果就是查詢到的購物車數據不完整,因此要想解決這個問題,我們就必須改造其中的代碼,把原本本地方法調用,改造成跨微服務的遠程調用(RPC,即Remote Produce Call)。
因此,現在查詢購物車列表的流程變成了這樣:
那么:我們該如何用Java代碼發送Http的請求呢?
RestTemplate
Spring給我們提供了一個RestTemplate的API,可以方便的實現Http請求的發送。
rg.springframework.web.client public class RestTemplate
extends InterceptingHttpAccessor
implements RestOperations
----------------------------------------------------------------------------------------------------------------
同步客戶端執行HTTP請求,在底層HTTP客戶端庫(如JDK HttpURLConnection、Apache HttpComponents等)上公開一個簡單的模板方法API。RestTemplate通過HTTP方法為常見場景提供了模板,此外還提供了支持不太常見情況的通用交換和執行方法。 RestTemplate通常用作共享組件。然而,它的配置不支持并發修改,因此它的配置通常是在啟動時準備的。如果需要,您可以在啟動時創建多個不同配置的RestTemplate實例。如果這些實例需要共享HTTP客戶端資源,它們可以使用相同的底層ClientHttpRequestFactory。 注意:從5.0開始,這個類處于維護模式,只有對更改和錯誤的小請求才會被接受。請考慮使用org.springframework.web.react .client. webclient,它有更現代的API,支持同步、異步和流場景。
其中提供了大量的方法,方便我們發送Http請求,例如:
可以看到常見的Get、Post、Put、Delete請求都支持,如果請求參數比較復雜,還可以使用exchange方法來構造請求。
我們在需要的微服務中定義一個配置類:
在啟動類中先將RestTemplate注冊為一個Bean:
@SpringBootApplication
public class CartApplication {public static void main(String[] args) {SpringApplication.run(CartApplication.class, args);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
遠程調用
接下來,我們修改cart-service
中的實現類的handleCartItems
方法,發送http請求到item-service
:
// 2.查詢商品
// List<ItemDTO> items = itemService.queryItemByIds(itemIds);//1.利用RestTemplate發起Http的請求,得到Http的響應ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://localhost:8081/items?ids={ids}",//請求路徑HttpMethod.GET,//請求方式null,//請求實體new ParameterizedTypeReference<List<ItemDTO>>() {},//返回值類型Map.of("ids", CollUtil.join(itemIds, ",")));//2.解析響應if (!response.getStatusCode().is2xxSuccessful()){//查詢失敗,結束return;}List<ItemDTO> items = response.getBody();if (CollUtils.isEmpty(items)) {return;}
可以看到,利用RestTemplate發送http請求與前端ajax發送請求非常相似,都包含四部分信息:
-
① 請求方式
-
② 請求路徑
-
③ 請求參數
-
④ 返回值類型
@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {private final RestTemplate restTemplate;
使用@RequiredArgsConstructor注解可以把final修飾的變量視為常量產生構造方法,比@AllArgsConstructor更適合