WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

今天就跟大家聊聊有關(guān)WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括高陵網(wǎng)站建設(shè)、高陵網(wǎng)站制作、高陵網(wǎng)頁制作以及高陵網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,高陵網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到高陵省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

當(dāng)WebClient請求發(fā)生異常的時(shí)候,該如何處理。為了講解異常處理,我們需要先制造出異常,所以我們先為大家介紹:請求超時(shí)時(shí)長的設(shè)置。

一、請求超時(shí)時(shí)長的設(shè)置

要想模擬超時(shí)異常,我們首先要知道超時(shí)時(shí)長的正常配置渠道是怎么樣的。如下文代碼所示:

  • ChannelOption.CONNECT_TIMEOUT_MILLIS用來設(shè)置連接超時(shí)時(shí)長,單位是毫秒

  • ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)用來設(shè)置讀數(shù)據(jù)超時(shí)時(shí)長,單位是毫秒

  • WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)用來設(shè)置寫數(shù)據(jù)超時(shí)時(shí)長,單位是毫秒

//初始化一個(gè)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();
}

當(dāng)我們把連接超時(shí)時(shí)長設(shè)置為5(毫秒)的時(shí)候,則連接肯定會超時(shí)。隨便發(fā)送一個(gè)請求,超時(shí)之后會拋出ConnectTimeoutException

WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

當(dāng)我們把讀數(shù)據(jù)超市時(shí)長設(shè)置為5(毫秒)的時(shí)候,則數(shù)據(jù)讀操作肯定會超時(shí)。隨便發(fā)送一個(gè)請求,超時(shí)之后會拋出ReadTimeoutException

WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

二、處理特定的異常

下面我們就以ConnectTimeoutException為例,進(jìn)行異常處理

//制造異常,將超時(shí)時(shí)間設(shè)置為5毫秒
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5)

然后執(zhí)行下面的GET請求,上文WebClient的baseurl為:"http://jsonplaceholder.typicode.com" ,該網(wǎng)站是一個(gè)免費(fèi)提供HTTP服務(wù)端測試的網(wǎng)站。

@Test
public void testSimple() throws Exception {
   Mono<String> mono = getWebClient()
               .get()    // 發(fā)送GET 請求
               .uri("/posts/1")  //服務(wù)請求路徑,基于baseurl
               .retrieve() // 獲取響應(yīng)體
               .bodyToMono(String.class) //響應(yīng)數(shù)據(jù)類型轉(zhuǎn)換
                //進(jìn)行異常處理
               .doOnError(ConnectTimeoutException.class, err -> {
                  System.out.println("發(fā)生錯(cuò)誤:" +err.getMessage() );
               });
   System.out.println(mono.block());
}

上文中的doOnError是我們本節(jié)為大家介紹的異常處理方法,用于處理ConnectTimeoutException,輸出結(jié)果如下:

WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

從輸出結(jié)果上看:一:異常得到處理,因?yàn)榭吹搅薙ystem.out打印日志。二是異常仍然被拋出了,沒有得到返回值。

三、請求異常給出默認(rèn)返回值

從第二小節(jié)中的代碼及控制臺輸出,可以看出HTTP 客戶端請求沒有得到返回值,而是繼續(xù)把異常對外拋出。假如我們目前的需求是,不論請求成功失敗,都給客戶端一個(gè)返回值,該怎么做?也就是說我們需要在請求發(fā)生異常的時(shí)候,給出默認(rèn)返回值。

@Test
public void testReturn() throws Exception {
   Mono<String> mono = getWebClient()
               .get()    // 發(fā)送GET 請求
               .uri("/posts/1")  //服務(wù)請求路徑,基于baseurl
               .retrieve() // 獲取響應(yīng)體
               .bodyToMono(String.class) //響應(yīng)數(shù)據(jù)類型轉(zhuǎn)換
               .doOnError(ConnectTimeoutException.class, err -> {
                  System.out.println("發(fā)生錯(cuò)誤:" +err.getMessage() );
               })
               .onErrorReturn("請求發(fā)生異常,請檢查!");
   System.out.println(mono.block());
}

使用onErrorReturn();給出請求的默認(rèn)返回值,輸出結(jié)果如下:

WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

可以看到請求測試用例成功pass了,因?yàn)槲覀兘o出了異常處理的默認(rèn)返回值,沒有把異常繼續(xù)拋出。

四、分類異常處理

上面的異常處理方法,只能處理指定的某種異常:ConnectTimeoutException。如果說我們想讓異常處理相對通用一些該怎么辦?有的小伙伴可能會想到攔截異常的父類Exception,當(dāng)然這也是一種辦法。

.doOnError(Exception.class, err -> {
   System.out.println("發(fā)生錯(cuò)誤:" +err.getMessage() );
});

我們下面為大家介紹一種,針對HTTP 響應(yīng)異常處理更友好的一種方式。通常來說,異??梢苑譃閮煞N:

  • 一種是客戶端輸入或訪問異常,比如:訪問的資源不存在404,沒有權(quán)限訪問資源403,輸入的數(shù)據(jù)不符合格式等等。這種異常通常是用戶訪問了不該訪問的資源,或者輸入了不該輸入的數(shù)據(jù)導(dǎo)致的。通常用HTTP狀態(tài)碼表示在400-499范圍內(nèi)。

  • 另一種是服務(wù)端內(nèi)部錯(cuò)誤,比如:500服務(wù)內(nèi)部錯(cuò)誤、502網(wǎng)關(guān)錯(cuò)誤等等。這種異常通常和用戶沒什么關(guān)系,是IT基礎(chǔ)設(shè)施或者編程導(dǎo)致的異常。

所以我們只需要針對上面的兩類異常進(jìn)行處理即可。如下文代碼所示:

  • e.is4xxClientError()表示的是400-499狀態(tài)碼段的異常

  • e.is5xxClientError()表示的是500-599狀態(tài)碼段的異常

public void testSimple2() throws Exception {
   Mono<String> mono = getWebClient()
               .get()    // 發(fā)送GET 請求
               .uri("/postss/1")  //服務(wù)請求路徑,基于baseurl
               .retrieve() // 獲取響應(yīng)體
               .onStatus(e -> e.is4xxClientError(), resp -> {
                  System.out.println("發(fā)生客戶端輸入錯(cuò)誤:" + resp.statusCode().value() + " "
                              + resp.statusCode().getReasonPhrase());
                  return Mono.error(new RuntimeException("請求失敗"));
               })
               .onStatus(e -> e.is5xxServerError(), resp -> {
                  System.out.println("發(fā)生服務(wù)端錯(cuò)誤:" + resp.statusCode().value() + " "
                              + resp.statusCode().getReasonPhrase());
                  return Mono.error(new RuntimeException("服務(wù)器異常"));
               })
               .bodyToMono(String.class); //響應(yīng)數(shù)據(jù)類型轉(zhuǎn)換
   System.out.println(mono.block());
}

現(xiàn)在我們將請求地址由正確的"/posts/1",改成錯(cuò)誤的"/postss/1",所以當(dāng)我們訪問服務(wù)端的時(shí)候,服務(wù)端并不存在這個(gè)資源。異常處理的輸出結(jié)果如下:

WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理

看完上述內(nèi)容,你們對WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

當(dāng)前名稱:WebClient中如何進(jìn)行請求超時(shí)設(shè)置與異常處理
URL網(wǎng)址:http://muchs.cn/article8/iepgop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT服務(wù)器托管、網(wǎng)站內(nèi)鏈虛擬主機(jī)、手機(jī)網(wǎng)站建設(shè)、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)