日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

別再使用 RestTemplate了,來了解一下官方推薦的 WebClient !

來源: 責編: 時間:2023-10-10 18:32:44 821觀看
導讀在 Spring Framework 5.0 及更高版本中,RestTemplate 已被棄用,取而代之的是較新的 WebClient。這意味著雖然 RestTemplate 仍然可用,但鼓勵 Spring 開發人員遷移到新項目的 WebClient。WebClient 優于 RestTemplate 的

在 Spring Framework 5.0 及更高版本中,RestTemplate 已被棄用,取而代之的是較新的 WebClient。這意味著雖然 RestTemplate 仍然可用,但鼓勵 Spring 開發人員遷移到新項目的 WebClient。45R28資訊網——每日最新資訊28at.com

WebClient 優于 RestTemplate 的原因有幾個:45R28資訊網——每日最新資訊28at.com

  • 非阻塞 I/O:WebClient 構建在 Reactor 之上,它提供了一種非阻塞、反應式的方法來處理 I/O。這可以在高流量應用程序中實現更好的可擴展性和更高的性能。
  • 函數式風格:WebClient 使用函數式編程風格,可以使代碼更易于閱讀和理解。它還提供了流暢的 API,可以更輕松地配置和自定義請求。
  • 更好地支持流式傳輸:WebClient 支持請求和響應正文的流式傳輸,這對于處理大文件或實時數據非常有用。
  • 改進的錯誤處理:WebClient 提供比 RestTemplate 更好的錯誤處理和日志記錄,從而更輕松地診斷和解決問題。

重點:即使升級了spring web 6.0.0版本,也無法在HttpRequestFactory中設置請求超時,這是放棄使用 RestTemplate 的最大因素之一。45R28資訊網——每日最新資訊28at.com

圖片圖片45R28資訊網——每日最新資訊28at.com

設置請求超時不會有任何影響45R28資訊網——每日最新資訊28at.com

總的來說,雖然 RestTemplate 可能仍然適用于某些用例,但 WebClient 提供了幾個優勢,使其成為現代 Spring 應用程序的更好選擇。45R28資訊網——每日最新資訊28at.com

讓我們看看如何在 SpringBoot 3 應用程序中使用 WebClient。45R28資訊網——每日最新資訊28at.com

(1) 創建網絡客戶端:

import ioty.channel.ChannelOption;import ioty.channel.ConnectTimeoutException;import ioty.handler.timeout.ReadTimeoutException;import ioty.handler.timeout.ReadTimeoutHandler;import ioty.handler.timeout.TimeoutException;import jakarta.annotation.PostConstruct;import java.time.Duration;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.HttpMethod;import org.springframework.http.MediaType;import org.springframework.http.client.reactive.ReactorClientHttpConnector;import org.springframework.stereotype.Service;import org.springframework.web.reactive.function.client.WebClient;import org.springframework.web.reactive.function.client.WebClientRequestException;import org.springframework.web.reactive.function.client.WebClientResponseException;import reactor.core.publisher.Mono;import reactorty.http.client.HttpClient;HttpClient httpClient =        HttpClient.create()            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)            .responseTimeout(Duration.ofMillis(requestTimeout))            .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(readTimeout)));   WebClient client =        WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();

(2) 同步發送請求(就像RestTemplate一樣)

如果你想堅持使用發送 HTTP 請求并等待響應的老方法,也可以使用 WebClient 實現如下所示的相同功能:45R28資訊網——每日最新資訊28at.com

public String postSynchronously(String url, String requestBody) {  LOG.info("Going to hit API - URL {} Body {}", url, requestBody);  String response = "";  try {    response =        client            .method(HttpMethod.POST)            .uri(url)            .accept(MediaType.ALL)            .contentType(MediaType.APPLICATION_JSON)            .bodyValue(requestBody)            .retrieve()            .bodyToMono(String.class)            .block();  } catch (Exception ex) {    LOG.error("Error while calling API ", ex);    throw new RunTimeException("XYZ service api error: " + ex.getMessage());  } finally {    LOG.info("API Response {}", response);  }  return response;}

block()用于同步等待響應,這可能并不適合所有情況,你可能需要考慮subscribe()異步使用和處理響應。45R28資訊網——每日最新資訊28at.com

(3) 異步發送請求:

有時我們不想等待響應,而是希望異步處理響應,這可以按如下方式完成:45R28資訊網——每日最新資訊28at.com

import org.springframework.http.MediaType;import org.springframework.web.reactive.function.BodyInserters;import org.springframework.web.reactive.function.client.WebClient;import reactor.core.publisher.Mono;public static Mono<String> makePostRequestAsync(String url, String postData) {    WebClient webClient = WebClient.builder().build();    return webClient.post()            .uri(url)            .contentType(MediaType.APPLICATION_FORM_URLENCODED)            .body(BodyInserters.fromFormData("data", postData))            .retrieve()            .bodyToMono(String.class);}

要使用此函數,只需傳入要向其發送 POST 請求的 URL 以及要在請求正文中以 URL 編碼字符串形式發送的數據。關注工眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部Java性能調優手冊!該函數將返回來自服務器的響應,或者如果請求由于任何原因失敗,則返回一條錯誤消息。45R28資訊網——每日最新資訊28at.com

請注意,在此示例中,WebClient是使用默認配置構建的。你可能需要根據不同要求進行不同的配置。45R28資訊網——每日最新資訊28at.com

另請注意,block()用于同步等待響應,這可能并不適合所有情況。你可能需要考慮subscribe()異步使用和處理響應。45R28資訊網——每日最新資訊28at.com

要使用響應,您可以訂閱Mono并異步處理響應。下面是一個例子:45R28資訊網——每日最新資訊28at.com

makePostRequestAsync( "https://example.com/api" , "param1=value1?m2=value2" ) .subscribe(response -> {     // 處理響應    System.out.println ( response ); }, error -> {     / / 處理錯誤    System.err.println ( error .getMessage ());         });

subscribe()用于異步處理響應,你可以提供兩個 lambda 表達式作為 subscribe() 的參數。如果請求成功并收到響應作為參數,則執行第一個 lambda 表達式;如果請求失敗并收到錯誤作為參數,則執行第二個 lambda 表達式。45R28資訊網——每日最新資訊28at.com

(4) 處理4XX和5XX錯誤:

import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.web.reactive.function.BodyInserters;import org.springframework.web.reactive.function.client.WebClient;import reactor.core.publisher.Mono;public static Mono<String> makePostRequestAsync(String url, String postData) {    WebClient webClient = WebClient.builder()            .baseUrl(url)            .build();    return webClient.post()            .uri("/")            .contentType(MediaType.APPLICATION_FORM_URLENCODED)            .body(BodyInserters.fromFormData("data", postData))            .retrieve()            .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new RuntimeException("Client error")))            .onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new RuntimeException("Server error")))            .bodyToMono(String.class);}

在此示例中,該onStatus()方法被調用兩次,一次針對 4xx 客戶端錯誤,一次針對 5xx 服務器錯誤。onStatus() 每次調用都采用兩個參數:45R28資訊網——每日最新資訊28at.com

  • aPredicate確定錯誤狀態代碼是否與條件匹配
  • aFunction用于返回Mono,即要傳播到訂閱者的錯誤信息。

如果狀態代碼與條件匹配,Mono則會發出相應的狀態代碼,并且Mono鏈會因錯誤而終止。在此示例中,Mono 將發出一條 RuntimeException 錯誤消息,指示該錯誤是客戶端錯誤還是服務器錯誤。45R28資訊網——每日最新資訊28at.com

(5) 根據錯誤狀態采取行動:

要根據Mono的subscribe()方法中的錯誤采取操作,可以在subscribe函數中處理響應的lambda表達式之后添加另一個lambda表達。如果在處理Monumber的過程中出現錯誤,則執行第二個lambda表達式。45R28資訊網——每日最新資訊28at.com

下面是如何使用makePostRequestAsync函數和處理subscribe方法中的錯誤的更新示例:45R28資訊網——每日最新資訊28at.com

makePostRequestAsync("https://example.com/api", "param1=value1?m2=value2").subscribe(response -> {    // handle the response    System.out.println(response);}, error -> {    // handle the error    System.err.println("An error occurred: " + error.getMessage());    if (error instanceof WebClientResponseException) {        WebClientResponseException webClientResponseException = (WebClientResponseException) error;        int statusCode = webClientResponseException.getStatusCode().value();        String statusText = webClientResponseException.getStatusText();        System.err.println("Error status code: " + statusCode);        System.err.println("Error status text: " + statusText);    }});

subscribe方法中的第二個lambda表達式檢查錯誤是否是WebClientResponseException的實例,這是WebClient在服務器有錯誤響應時拋出的特定類型的異常。如果它是WebClientResponseException的實例,則代碼將從異常中提取狀態代碼和狀態文本,并將它們記錄到日志中。45R28資訊網——每日最新資訊28at.com

還可以根據發生的特定錯誤在此lambda表達式中添加其他錯誤處理邏輯。例如,你可以重試請求、回退到默認值或以特定方式記錄錯誤。45R28資訊網——每日最新資訊28at.com

(6) 處理成功響應和錯誤的完整代碼:

responseMono.subscribe(response -> {  // handle the response  LOG.info("SUCCESS API Response {}", response);},error -> {  // handle the error  LOG.error("An error occurred: {}", error.getMessage());  LOG.error("error class: {}", error.getClass());  // Errors / Exceptions from Server  if (error instanceof WebClientResponseException) {    WebClientResponseException webClientResponseException =        (WebClientResponseException) error;    int statusCode = webClientResponseException.getStatusCode().value();    String statusText = webClientResponseException.getStatusText();    LOG.info("Error status code: {}", statusCode);    LOG.info("Error status text: {}", statusText);    if (statusCode >= 400 && statusCode < 500) {      LOG.info(          "Error Response body {}", webClientResponseException.getResponseBodyAsString());    }    Throwable cause = webClientResponseException.getCause();    LOG.error("webClientResponseException");    if (null != cause) {      LOG.info("Cause {}", cause.getClass());      if (cause instanceof ReadTimeoutException) {        LOG.error("ReadTimeout Exception");      }      if (cause instanceof TimeoutException) {        LOG.error("Timeout Exception");      }    }  }  // Client errors i.e. Timeouts etc -   if (error instanceof WebClientRequestException) {    LOG.error("webClientRequestException");    WebClientRequestException webClientRequestException =        (WebClientRequestException) error;    Throwable cause = webClientRequestException.getCause();    if (null != cause) {      LOG.info("Cause {}", cause.getClass());      if (cause instanceof ReadTimeoutException) {        LOG.error("ReadTimeout Exception");      }            if (cause instanceof ConnectTimeoutException) {        LOG.error("Connect Timeout Exception");      }    }  }});

超時

我們可以在每個請求中設置超時,如下所示:45R28資訊網——每日最新資訊28at.com

return webClient    .method(this.httpMethod)    .uri(this.uri)    .headers(httpHeaders -> httpHeaders.addAll(additionalHeaders))    .bodyValue(this.requestEntity)    .retrieve()    .bodyToMono(responseType)    .timeout(Duration.ofMillis(readTimeout))  // request timeout for this request    .block();

但是,我們無法在每個請求中設置連接超時,這是WebClient 的屬性,只能設置一次。如果需要,我們始終可以使用新的連接超時值創建一個新的 Web 客戶端實例。45R28資訊網——每日最新資訊28at.com

連接超時、讀取超時和請求超時的區別如下:45R28資訊網——每日最新資訊28at.com

圖片圖片45R28資訊網——每日最新資訊28at.com

結論

由于 RestTemplace 已棄用,開發人員應開始使用 WebClient 進行 REST 調用,非阻塞 I/O 調用肯定會提高應用程序性能。它不僅提供了許多其他令人興奮的功能,例如改進的錯誤處理和對流的支持,而且如果需要,它還可以在阻塞模式下使用來模擬 RestTemplate 行為。45R28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-12765-0.html別再使用 RestTemplate了,來了解一下官方推薦的 WebClient !

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 使用Optional優雅避免空指針異常

下一篇: Promise 和 Async/Await的區別

標簽:
  • 熱門焦點
  • Redmi Pad評測:紅米充滿野心的一次嘗試

    從Note系列到K系列,從藍牙耳機到筆記本電腦,紅米不知不覺之間也已經形成了自己頗有競爭力的產品體系,在中端和次旗艦市場上甚至要比小米新機的表現來得更好,正所謂“大丈夫生居
  • 6月安卓手機好評榜:魅族20 Pro蟬聯冠軍

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年6月1日至6月30日,僅限國內市場。第一名:魅族20 Pro好評率:95%5月份的時候魅族20 Pro就是
  • 轎車從天而降電動車主被撞身亡 超速搶道所致:現場視頻讓網友吵翻

    近日,上海青浦區法院判決轎車從天而降電動車主被撞身亡案,轎車車主被判有期徒刑一年。案件顯示當時男子駕駛轎車在上海某路段行駛,前車忽然轉彎提速超車,
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 慕巖炮轟抖音,百合網今何在?

    來源:價值研究所 作者:Hernanderz&ldquo;難道就因為自己的一個產品牛逼了,從客服到總裁,都不愿意正視自己產品和運營上的問題,選擇逃避了嗎?&rdquo;這一番話,出自百合網聯合創
  • 騰訊蓋樓,字節拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • 花7萬退貨退款無門:誰在縱容淘寶珠寶商家造假?

    來源:極點商業作者:楊銘在淘寶購買珠寶玉石后,因為保證金不夠賠付,店鋪關閉,退貨退款難、維權無門的比比皆是。&ldquo;提供相關產品鑒定證書,支持全國復檢,可以30天無理由退換貨。&
  • OPPO K11樣張首曝:千元機影像“卷”得真不錯!

    一直以來,OPPO K系列機型都保持著較為均衡的產品體驗,歷來都是2K價位的明星機型,去年推出的OPPO K10和OPPO K10 Pro兩款機型憑借各自的出色配置,堪稱有
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 名山县| 专栏| 醴陵市| 方城县| 盐边县| 临夏市| 云浮市| 灵寿县| 株洲市| 北票市| 孟州市| 丁青县| 池州市| 南部县| 镇巴县| 永吉县| 义乌市| 巫山县| 冕宁县| 庆阳市| 博乐市| 塔城市| 安顺市| 福清市| 南靖县| 龙海市| 台湾省| 汉中市| 铜梁县| 郧西县| 台安县| 南郑县| 灵璧县| 肃北| 永顺县| 乌海市| 延津县| 塘沽区| 泌阳县| SHOW| 桐柏县|