欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?WebFlux怎么進(jìn)行異常處理源碼解析

 更新時(shí)間:2023年08月25日 11:47:30   作者:六七十三  
這篇文章主要為大家介紹了Spring?WebFlux怎么進(jìn)行異常處理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1 概覽

在本教程中,我們將通過(guò)一個(gè)實(shí)際示例了解Spring WebFlux項(xiàng)目中處理錯(cuò)誤的各種策略。

我們還將指出使用一種策略比另一種策略更有利的地方,并在最后提供完整源代碼的鏈接。

2 開(kāi)始示例代碼

maven 設(shè)置和之前介紹 Spring WebFlux 的文章一樣,

對(duì)于我們的示例,我們將使用一個(gè) RESTful 端點(diǎn),它將用戶(hù)名作為查詢(xún)參數(shù)并返回“Hello username”作為結(jié)果。首先,讓我們創(chuàng)建一個(gè)路由函數(shù),這個(gè)路由函數(shù)將 “/hello” 請(qǐng)求路由到處理程序中名為 handleRequest 的方法,代碼如下:

@Bean
public RouterFunction<ServerResponse> routeRequest(Handler handler) {
    return RouterFunctions.route(RequestPredicates.GET("/hello")
      .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), 
        handler::handleRequest);
    }

然后,我們定義個(gè) handleRequest() 方法,這個(gè)方法調(diào)用 sayHello() 方法,并找到一個(gè)在 ServerResponse 中包含或返回其(sayHello方法的返回)結(jié)果的方法。

public Mono<ServerResponse> handleRequest(ServerRequest request) {
    return 
      //...
        sayHello(request)
      //...
}

最后,實(shí)現(xiàn) sayHello 方法,實(shí)現(xiàn)很簡(jiǎn)單,直接拼接 hello 和參數(shù) username 即可。

private Mono<String> sayHello(ServerRequest request) {
    try {
        // 應(yīng)該是 username
        return Mono.just("Hello, " + request.queryParam("username").get());
    } catch (Exception e) {
        return Mono.error(e);
    }
}

因此,只要我們的請(qǐng)求中帶了 username 參數(shù),我們的請(qǐng)求就能正常返回。舉個(gè)例子:我們請(qǐng)求“/hello?username=Tonni”,類(lèi)似請(qǐng)求,我們總是能正常返回。

然而,如果我們的請(qǐng)求不帶 username 參數(shù),我們的請(qǐng)求就會(huì)拋出異常了。下面,我們來(lái)看看 Spring WebFlux 在哪里以及怎么重組代碼來(lái)處理我們的異常。

3 方法級(jí)別處理異常

Mono 和 Flux API 中內(nèi)置了兩個(gè)關(guān)鍵運(yùn)算符來(lái)處理方法級(jí)別的錯(cuò)誤。我們簡(jiǎn)要探討一下它們及其用法。

3.1 onErrorReturn 處理異常

當(dāng)我們碰到異常的時(shí)候,我們可以用 onErrorReturn 來(lái)直接返回靜態(tài)結(jié)果:

public Mono<ServerResponse> handleRequest(ServerRequest request) {
    return sayHello(request)
      .onErrorReturn("Hello Stranger")
      .flatMap(s -> ServerResponse.ok()
        .contentType(MediaType.TEXT_PLAIN)
        .bodyValue(s));
}

這里,每當(dāng)有問(wèn)題的連接函數(shù)拋出異常的時(shí)候,我們直接返回一個(gè)靜態(tài)結(jié)果:“Hello Stranger”。

3.2 onErrorResume 處理異常

有三種使用 onErrorResume 處理異常的方式:

  • 計(jì)算動(dòng)態(tài)回調(diào)值
  • 通過(guò)回調(diào)函數(shù)執(zhí)行其他分支
  • 捕獲、包裝并重新拋出錯(cuò)誤,例如,作為自定義業(yè)務(wù)異常

讓我們看看怎么計(jì)算值:

public Mono<ServerResponse> handleRequest(ServerRequest request) {
    return sayHello(request)
      .flatMap(s -> ServerResponse.ok()
        .contentType(MediaType.TEXT_PLAIN)
        .bodyValue(s))
      .onErrorResume(e -> Mono.just("Error " + e.getMessage())
        .flatMap(s -> ServerResponse.ok()
          .contentType(MediaType.TEXT_PLAIN)
          .bodyValue(s)));
}

這里,每當(dāng) sayHello 拋出異常的時(shí)候,我們返回一個(gè) “Error + 異常信息(e.getMessage())”。

接下來(lái),我們看看當(dāng)異常發(fā)生調(diào)用回調(diào)函數(shù):

public Mono<ServerResponse> handleRequest(ServerRequest request) {
    return sayHello(request)
      .flatMap(s -> ServerResponse.ok()
        .contentType(MediaType.TEXT_PLAIN)
        .bodyValue(s))
      .onErrorResume(e -> sayHelloFallback()
        .flatMap(s -> ServerResponse.ok()
        .contentType(MediaType.TEXT_PLAIN)
        .bodyValue(s)));
}

這里,每當(dāng) sayHello 拋出異常的時(shí)候,我們執(zhí)行一個(gè)其他函數(shù) sayHelloFallback 。

最后,使用 onErrorResume 來(lái)捕獲、包裝并重新拋出錯(cuò)誤,舉例如:NameRequiredException

public Mono<ServerResponse> handleRequest(ServerRequest request) {
    return ServerResponse.ok()
      .body(sayHello(request)
      .onErrorResume(e -> Mono.error(new NameRequiredException(
        HttpStatus.BAD_REQUEST, 
        "username is required", e))), String.class);
}

這里,當(dāng) sayHello 拋出異常的時(shí)候,我們拋出一個(gè)定制異常 NameRequiredException,message是 “username is required”。

全局處理異常

目前為止,我們提供的所有示例都在方法級(jí)別上處理了錯(cuò)誤處理。但是我們可以選擇在全局層面處理異常。為此,我們只需要兩步:

  • 自定義一個(gè)全局錯(cuò)誤響應(yīng)屬性
  • 實(shí)現(xiàn)全局錯(cuò)誤處理 handler

這樣我們程序拋出的異常將會(huì)自動(dòng)轉(zhuǎn)換成 HTTP 狀態(tài)和 JSON 錯(cuò)誤體。我們只需要繼承 DefaultErrorAttributes 類(lèi)然后重寫(xiě) getErrorAttributes 方法就可以自定義這些。

public class GlobalErrorAttributes extends DefaultErrorAttributes{
    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request, 
      ErrorAttributeOptions options) {
        Map<String, Object> map = super.getErrorAttributes(
          request, options);
        map.put("status", HttpStatus.BAD_REQUEST);
        map.put("message", "username is required");
        return map;
    }
}

這里,當(dāng)異常拋出是,我們想要返回 BAD_REQUEST 狀態(tài)碼和“username is required”錯(cuò)誤信息作為錯(cuò)誤屬性的一部分。

然后,我們來(lái)實(shí)現(xiàn)全局錯(cuò)誤處理 handler。

為此,Spring 提供了一個(gè)方便的 AbstractErrorWebExceptionHandler 類(lèi),供我們?cè)谔幚砣皱e(cuò)誤時(shí)進(jìn)行擴(kuò)展和實(shí)現(xiàn):

@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends 
    AbstractErrorWebExceptionHandler {
    // constructors
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(
      ErrorAttributes errorAttributes) {
        return RouterFunctions.route(
          RequestPredicates.all(), this::renderErrorResponse);
    }
    private Mono<ServerResponse> renderErrorResponse(
       ServerRequest request) {
       Map<String, Object> errorPropertiesMap = getErrorAttributes(request, 
         ErrorAttributeOptions.defaults());
       return ServerResponse.status(HttpStatus.BAD_REQUEST)
         .contentType(MediaType.APPLICATION_JSON)
         .body(BodyInserters.fromValue(errorPropertiesMap));
    }
}

在這個(gè)例子中,我們?cè)O(shè)置 handler 的 order 為 -2。這是為了給它一個(gè)比默認(rèn) handler,也就是 DefaultErrorWebExceptionHandler 一個(gè)更高的優(yōu)先級(jí),它設(shè)置的 order 為 -1。

errorAttributes 對(duì)象將是我們?cè)?Web 異常處理程序的構(gòu)造函數(shù)中傳遞的對(duì)象的精確副本。理想情況下,這應(yīng)該是我們自定義的錯(cuò)誤屬性類(lèi)。

然后我們明確生命了,我們希望將所有的異常處理路由到 renderErrorResponse() 中。

最后,我們獲取了錯(cuò)誤屬性并插入到服務(wù)端響應(yīng)體中。

然后這會(huì)生成一個(gè) JSON 響應(yīng),其中包含了錯(cuò)誤的詳細(xì)信息,HTTP 狀態(tài)、機(jī)器端的異常信息等。對(duì)于瀏覽器端,它有一個(gè) “white-label”錯(cuò)誤處理程序,可以以 HTML 形式呈現(xiàn)相同的數(shù)據(jù),當(dāng)然這個(gè)頁(yè)面可以定制。

總結(jié)

在本文中,我們研究了在 Spring WebFlux 項(xiàng)目中處理異常的集中策略,并指出使用一個(gè)策略?xún)?yōu)于其他策略的地方。

源碼在 github 上

翻譯自原文:https://www.baeldung.com/spri...

以上就是Spring WebFlux怎么進(jìn)行異常處理源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Spring WebFlux異常處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring集成Mybatis過(guò)程詳細(xì)講解

    Spring集成Mybatis過(guò)程詳細(xì)講解

    mybatis-plus是一個(gè)Mybatis的增強(qiáng)工具,在Mybatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生,下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合Mybatis-plus案例及用法實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • Java實(shí)現(xiàn)獲取cpu、內(nèi)存、硬盤(pán)、網(wǎng)絡(luò)等信息的方法示例

    Java實(shí)現(xiàn)獲取cpu、內(nèi)存、硬盤(pán)、網(wǎng)絡(luò)等信息的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)獲取cpu、內(nèi)存、硬盤(pán)、網(wǎng)絡(luò)等信息的方法,涉及java使用第三方j(luò)ar包針對(duì)本機(jī)硬件的cpu、內(nèi)存、硬盤(pán)、網(wǎng)絡(luò)信息等的讀取相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • 如何將maven項(xiàng)目劃分為多個(gè)模塊

    如何將maven項(xiàng)目劃分為多個(gè)模塊

    這篇文章主要介紹了如何將maven項(xiàng)目劃分為多個(gè)模塊,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn)

    Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn)

    這篇文章主要介紹了Mybatis返回單個(gè)實(shí)體或者返回List的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Jar包如何導(dǎo)入本地maven倉(cāng)庫(kù)

    Jar包如何導(dǎo)入本地maven倉(cāng)庫(kù)

    將本地jar包導(dǎo)入本地maven倉(cāng)庫(kù),可以通過(guò)maven命令-Dfile、-DgroupId、-DartifactId、-Dversion、-Dpackaging指定jar包的詳細(xì)信息,然后執(zhí)行命令即可
    2024-11-11
  • MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路

    MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路

    這篇文章主要介紹了MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無(wú)法識(shí)別即未被標(biāo)識(shí)的解決辦法

    IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無(wú)法識(shí)別即未被標(biāo)識(shí)的解決辦法

    在學(xué)習(xí)SpringMVC課程中,基于IDEA新建maven項(xiàng)目模塊后,webapp目錄未被標(biāo)識(shí),即沒(méi)有小藍(lán)點(diǎn)的圖標(biāo)顯示,所以本文給大家介紹了IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無(wú)法識(shí)別即未被標(biāo)識(shí)的解決辦法,需要的朋友可以參考下
    2024-03-03
  • 淺析Spring和MyBatis整合及逆向工程

    淺析Spring和MyBatis整合及逆向工程

    這篇文章主要介紹了Spring和MyBatis整合及逆向工程的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • spring的13個(gè)經(jīng)典面試題

    spring的13個(gè)經(jīng)典面試題

    Spring框架是一個(gè)開(kāi)放源代碼的J2EE應(yīng)用程序框架,是針對(duì)bean的生命周期進(jìn)行管理的輕量級(jí)容Spring解決了開(kāi)發(fā)者在J2EE開(kāi)發(fā)中遇到的許多常見(jiàn)的問(wèn)題,我們這篇文章就來(lái)了解一下spring的面試題
    2021-06-06
  • 自主配置數(shù)據(jù)源,mybatis/plus不打印sql日志問(wèn)題

    自主配置數(shù)據(jù)源,mybatis/plus不打印sql日志問(wèn)題

    這篇文章主要介紹了自主配置數(shù)據(jù)源,mybatis/plus不打印sql日志問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論