您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關WebClient中如何進行請求超時設置與異常處理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
當WebClient請求發生異常的時候,該如何處理。為了講解異常處理,我們需要先制造出異常,所以我們先為大家介紹:請求超時時長的設置。
要想模擬超時異常,我們首先要知道超時時長的正常配置渠道是怎么樣的。如下文代碼所示:
ChannelOption.CONNECT_TIMEOUT_MILLIS
用來設置連接超時時長,單位是毫秒
ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)
用來設置讀數據超時時長,單位是毫秒
WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)
用來設置寫數據超時時長,單位是毫秒
//初始化一個WebClient private WebClient getWebClient(){ TcpClient tcpClient = TcpClient .create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) .doOnConnected(connection -> { connection.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)); connection.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)); }); return WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) .build(); }
當我們把連接超時時長設置為5(毫秒)的時候,則連接肯定會超時。隨便發送一個請求,超時之后會拋出ConnectTimeoutException
當我們把讀數據超市時長設置為5(毫秒)的時候,則數據讀操作肯定會超時。隨便發送一個請求,超時之后會拋出ReadTimeoutException
下面我們就以ConnectTimeoutException為例,進行異常處理
//制造異常,將超時時間設置為5毫秒 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5)
然后執行下面的GET請求,上文WebClient的baseurl為:"http://jsonplaceholder.typicode.com" ,該網站是一個免費提供HTTP服務端測試的網站。
@Test public void testSimple() throws Exception { Mono<String> mono = getWebClient() .get() // 發送GET 請求 .uri("/posts/1") //服務請求路徑,基于baseurl .retrieve() // 獲取響應體 .bodyToMono(String.class) //響應數據類型轉換 //進行異常處理 .doOnError(ConnectTimeoutException.class, err -> { System.out.println("發生錯誤:" +err.getMessage() ); }); System.out.println(mono.block()); }
上文中的doOnError是我們本節為大家介紹的異常處理方法,用于處理ConnectTimeoutException,輸出結果如下:
從輸出結果上看:一:異常得到處理,因為看到了System.out打印日志。二是異常仍然被拋出了,沒有得到返回值。
從第二小節中的代碼及控制臺輸出,可以看出HTTP 客戶端請求沒有得到返回值,而是繼續把異常對外拋出。假如我們目前的需求是,不論請求成功失敗,都給客戶端一個返回值,該怎么做?也就是說我們需要在請求發生異常的時候,給出默認返回值。
@Test public void testReturn() throws Exception { Mono<String> mono = getWebClient() .get() // 發送GET 請求 .uri("/posts/1") //服務請求路徑,基于baseurl .retrieve() // 獲取響應體 .bodyToMono(String.class) //響應數據類型轉換 .doOnError(ConnectTimeoutException.class, err -> { System.out.println("發生錯誤:" +err.getMessage() ); }) .onErrorReturn("請求發生異常,請檢查!"); System.out.println(mono.block()); }
使用onErrorReturn();
給出請求的默認返回值,輸出結果如下:
可以看到請求測試用例成功pass了,因為我們給出了異常處理的默認返回值,沒有把異常繼續拋出。
上面的異常處理方法,只能處理指定的某種異常:ConnectTimeoutException。如果說我們想讓異常處理相對通用一些該怎么辦?有的小伙伴可能會想到攔截異常的父類Exception,當然這也是一種辦法。
.doOnError(Exception.class, err -> { System.out.println("發生錯誤:" +err.getMessage() ); });
我們下面為大家介紹一種,針對HTTP 響應異常處理更友好的一種方式。通常來說,異常可以分為兩種:
一種是客戶端輸入或訪問異常,比如:訪問的資源不存在404,沒有權限訪問資源403,輸入的數據不符合格式等等。這種異常通常是用戶訪問了不該訪問的資源,或者輸入了不該輸入的數據導致的。通常用HTTP狀態碼表示在400-499范圍內。
另一種是服務端內部錯誤,比如:500服務內部錯誤、502網關錯誤等等。這種異常通常和用戶沒什么關系,是IT基礎設施或者編程導致的異常。
所以我們只需要針對上面的兩類異常進行處理即可。如下文代碼所示:
e.is4xxClientError()表示的是400-499狀態碼段的異常
e.is5xxClientError()表示的是500-599狀態碼段的異常
public void testSimple2() throws Exception { Mono<String> mono = getWebClient() .get() // 發送GET 請求 .uri("/postss/1") //服務請求路徑,基于baseurl .retrieve() // 獲取響應體 .onStatus(e -> e.is4xxClientError(), resp -> { System.out.println("發生客戶端輸入錯誤:" + resp.statusCode().value() + " " + resp.statusCode().getReasonPhrase()); return Mono.error(new RuntimeException("請求失敗")); }) .onStatus(e -> e.is5xxServerError(), resp -> { System.out.println("發生服務端錯誤:" + resp.statusCode().value() + " " + resp.statusCode().getReasonPhrase()); return Mono.error(new RuntimeException("服務器異常")); }) .bodyToMono(String.class); //響應數據類型轉換 System.out.println(mono.block()); }
現在我們將請求地址由正確的"/posts/1",改成錯誤的"/postss/1",所以當我們訪問服務端的時候,服務端并不存在這個資源。異常處理的輸出結果如下:
看完上述內容,你們對WebClient中如何進行請求超時設置與異常處理有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。