-
後端專案完成後,除了前後端分離模式的前端對後端請求的需要,如Vue透過Axios.js元件請求後端REST介面;不同後端系統中也需要進行相互的HTTP請求,實現各業務系統的業務互動;如訂單服務,會呼叫支付服務、庫存服務、積分服務等,如下圖
後端HTTP請求圖 -
JDK的java.net包中已經提供了訪問HTTP協議的基本功能,主要是HttpUrlConnection,但是對於大部分應用程式來說,JDK庫本身提供的功能還是不夠豐富和靈活,會使用一些簡單、靈活的工具
-
基於Spring Boot的HTTP請求工具主要有
-
Http Client:Apache下的HTTP請求子專案,相對複雜,可配置連線池等引數
-
OkHttp3:類似於Http Client,但效能更好,也可配置連線池等引數
-
RestTemplate:Spring下的Rest請求工具,方便使用,預設使用HttpUrlConnection,可整合OkHttp
-
OpenFeign: Netflix開發的宣告式、模板化的HTTP客戶端, Feign可以幫助我們更快捷、優雅地呼叫HTTP API
-
WebClient:非阻塞的基於響應式程式設計的進行Http請求的客戶端工具,效能更好,Spring 5開始提供
-
RestTemplate
概述
-
RestTemplate是Spring 提供的用於訪問其他REST服務的元件
-
RestTemplate 提供了多種便捷訪問遠端HTTP服務的方法,能夠大大提高客戶端的編寫效率
-
底層預設使用HttpUrlConnection傳送HTTP請求,可切換成其他效能更好的工具,如OkHttp3
-
可以新增攔截工具,對請求/響應進行相應處理,透過實現ClientHttpRequestInterceptor介面,並覆蓋intercept方法,並新增到RestTemplate實現,比如,對每個請求新增token
-
特點
-
靈活,在程式中任意位置靈活使用
-
常用方法
-
getForXXX(),進行常用的GET請求操作
-
postForXXX(),進行常用的POST請求操作
-
exchange(),進行其他請求操作,因為針對其他HTTP請求操作,沒有定義特別多的操作方式,使用通用的exchange()進行
使用步驟
-
定義請求攔截器,實現ClientHttpRequestInterceptor介面,並覆蓋intercept方法,【可選】;見附件程式碼中的interceptor.RestTemplateClientHttpRequestInterceptor類
-
注入RestTemplate物件,注入RestTemplate物件到Spring容器,並可繫結請求攔截器;見附件程式碼中的config.RestTemplateConfig類
-
使用RestTemplate物件,其豐富的方法實現對其他REST服務進行呼叫;見附件程式碼中的remote.BugRemote類
【演示】
-
Spring Boot中使用RestTemplate對其他REST服務進行呼叫,見附件專案springboot-resttemplate中的類
-
config\RestTemplateConfig類,注入RestTemplate物件
-
remote\BugRemote類,使用RestTemplate物件
-
interceptor\RestTemplateClientHttpRequestInterceptor類,請求攔截器
-
OpenFeign
概述
-
Netflix開發的宣告式、模板化的HTTP客戶端,OpenFeign可以幫助我們更快捷、優雅地呼叫其他REST服務
-
預設使用HttpUrlConnection傳送HTTP請求,沒有連線池,但是對每個地址會保持一個長連線
-
可使用其他底層工具進行替換,比如Apache的Http Client或OkHttp3
-
特點
-
使用簡單,但不夠靈活,一般應用於固定介面呼叫,透過模擬成RestController形式進行呼叫
-
使用步驟
-
新增依賴:在pom.xml中引入依賴spring-cloud-starter-openfeign,注意版本匹配
<!--【OpenFeign】1、新增依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.8</version> </dependency>
-
新增啟動註解:在啟動類上新增@EnableFeignClients註解
-
定義遠端服務匹配介面:定義與被呼叫第三方服務匹配的介面並新增註解@FeignClient,指定name和url,程式碼片斷如下
/** * Bug遠端呼叫類 * 【OpenFeign】3、定義遠端服務匹配介面,使用配置在application.properties中的遠端服務主機地址URL */ @FeignClient(name = "bug",url="${remoteprj.base_url}/bug") public interface BugRemote { }
-
定義遠端服務匹配方法簽名:在上一步定義的遠端服務匹配介面中,定義與被呼叫第三方服務匹配的方法簽名和對映,程式碼片斷如下
/** * 分頁查詢 * 【OpenFeign】4、定義遠端服務匹配方法簽名 */ @GetMapping("/") ResponseData<List<BugOutputDto>> query(@RequestParam(defaultValue = "1")Long pageIndex,@RequestParam(defaultValue = "5") Long pageSize,@RequestParam Integer gradeId, @RequestParam String title);
-
新增呼叫日誌:新增日誌配置類,並在application.properties中新增放開debugger日誌的配置,程式碼片斷如下,【可選】
-
日誌類
package com.example.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class OpenFeignConfig { /** * 【OpenFeign】5、新增呼叫日誌,與application.properties中的配置配合使用 * @return */ @Bean Logger.Level feignLoggerLeave(){ return Logger.Level.FULL; } }
-
application.properties配置
#【OpenFeign】5、新增呼叫日誌 feign.httpclient.enabled=true logging.level.com.example.remote.*=debug
-
-
新增請求攔截器,實現RequestInterceptor介面,覆蓋apply方法,新增@Component註解自動注入到Spring容器,在方法中往請求中新增請求資訊,程式碼片斷如下,【可選】
package com.example.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 【OpenFeign】6、新增請求攔截器,【可選】 */ @Component @Slf4j public class OpenFeignRequestInterceptor implements RequestInterceptor { //配置的Token @Value("${remoteprj.token}") String token; @Override public void apply(RequestTemplate template) { //新增請求日誌 log.info("【OpenFeign】請求攔截"); //請求新增Token template.header("token",token); } }
-
使用遠端服務:在需要使用的地方使用自動裝配第3步定義的介面,並使用匹配簽名方法,即可實現對遠端服務的呼叫
【演示】
-
Spring Boot中使用OpenFeign對其他REST服務進行呼叫,見附件專案springboot-openfeign中的類
-
啟動類,新增@EnableFeignClients註解
-
remote\BugRemote類,使用OpenFeign功能
-
interceptor\OpenFeignRequestInterceptor類,攔截器類
-
config\OpenFeignConfig類,配置application.properties,新增呼叫日誌
-
程式碼
網盤地址:連結:https://pan.baidu.com/s/1wu7I1oiMC50MESKysOuGqQ?pwd=8888