成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring Boot 2.x 系列教程:WebFlux REST API 全局異常處理 Error

BicycleWarrior / 834人閱讀

摘要:挺多人咨詢的,異常處理用切面注解去實現(xiàn)去全局異常處理。全局異常處理類,代碼如下代碼解析如下抽象類是用來處理全局錯誤時進(jìn)行擴(kuò)展和實現(xiàn)注解標(biāo)記的切面排序,值越小擁有越高的優(yōu)先級,這里設(shè)置優(yōu)先級偏高。

本文內(nèi)容

為什么要全局異常處理?

WebFlux REST 全局異常處理實戰(zhàn)

小結(jié)

摘錄:只有不斷培養(yǎng)好習(xí)慣,同時不斷打破壞習(xí)慣,我們的行為舉止才能夠自始至終都是正確的。
一、為什么要全局異常處理?

前后端分離開發(fā),一般提供 REST API,正常返回會有響應(yīng)體,異常情況下會有對應(yīng)的錯誤碼響應(yīng)。

挺多人咨詢的,Spring Boot MVC 異常處理用切面 @RestControllerAdvice 注解去實現(xiàn)去全局異常處理。那 WebFlux 如何處理異常?如何實現(xiàn)統(tǒng)一錯誤碼異常處理?

全局異常處理的好處:

異常錯誤碼等統(tǒng)一維護(hù)

避免一些重復(fù)代碼

二、WebFlux REST 全局異常處理實戰(zhàn)

下面介紹如何統(tǒng)一攔截異常,進(jìn)行響應(yīng)處理。

2.1 工程信息

運(yùn)行環(huán)境:JDK 7 或 8,Maven 3.0+

技術(shù)棧:SpringBoot 2.1.3

代碼地址:https://github.com/JeffLi1993...

模塊工程名: 2-x-spring-boot-webflux-handling-errors

工程結(jié)構(gòu):

├── pom.xml
└── src
    └── main
        ├── java
        │?? └── org
        │??     └── spring
        │??         └── springboot
        │??             ├── Application.java
        │??             ├── error
        │??             │?? ├── GlobalErrorAttributes.java
        │??             │?? ├── GlobalErrorWebExceptionHandler.java
        │??             │?? └── GlobalException.java
        │??             ├── handler
        │??             │?? └── CityHandler.java
        │??             └── router
        │??                 └── CityRouter.java
        └── resources
            └── application.properties

application.properties 無須配置,默認(rèn)即可
Application Spring Boot 應(yīng)用啟動類,是可以用來啟動 Spring Boot 應(yīng)用。其包含了 @SpringBootApplication 注解和 SpringApplication 類,并調(diào)用 SpringApplication 類的 run() 方法,就可以啟動該應(yīng)用。

具體實現(xiàn)類的關(guān)系圖如下:

圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272

2.2 CityRouter 路由器類

城市路由器代碼如下:

@Configuration
public class CityRouter {
    
    @Bean
    public RouterFunction routeCity(CityHandler cityHandler) {
        return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity);
    }
    
}

RouterFunctions 對請求路由處理類,即將請求路由到處理器,這將一個 GET 請求 /hello 路由到處理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 類似。

RouterFunctions.route(RequestPredicate, HandlerFunction) 方法,對應(yīng)的 參是請求參數(shù)和處理函數(shù),如果請求匹配,就調(diào) 對應(yīng)的處理器函數(shù)。

2.3 CityHandler 服務(wù)處理類

城市服務(wù)器處理類,代碼如下:

@Component
public class CityHandler {
    
    public Mono helloCity(ServerRequest request) {
        return ServerResponse.ok().body(sayHelloCity(request), String.class);
    }
    
    private Mono sayHelloCity(ServerRequest request) {
        Optional cityParamOptional = request.queryParam("city");
        if (!cityParamOptional.isPresent()) {
            throw new GlobalException(HttpStatus.INTERNAL_SERVER_ERROR, "request param city is ERROR");
        }
        
        return Mono.just("Hello," + cityParamOptional.get());
    }
}

Mono:實現(xiàn)發(fā)布者,并返回 0 或 1 個元素,即單對象。Mono 是響應(yīng)流 Publisher 具有基礎(chǔ) rx 操作符。可以成功發(fā)布元素或者錯誤。用 Mono 作為返回對象,是因為返回包含了一個 ServerResponse 對象,而不是多個元素。

ServerResponse 是對響應(yīng)的封裝,可以設(shè)置響應(yīng)狀態(tài),響應(yīng)頭,響應(yīng)正文。比如 ok 代表的是 200 響應(yīng)碼、MediaType 枚舉是代表這文本內(nèi)容類型、返回的是 String 的對象。

ServerRequest 是對請求的封裝。從請求中拿出 city 的值,如果沒有的話則拋出對應(yīng)的異常。GlobalException 是封裝的全局異常。

Mono.justOrEmpty():從一個 Optional 對象或 null 對象中創(chuàng)建 Mono。

2.4 GlobalError 處理類

如圖:

圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272

GlobalException 全局異常類,代碼如下:

public class GlobalException extends ResponseStatusException {
    
    public GlobalException(HttpStatus status, String message) {
        super(status, message);
    }
    
    public GlobalException(HttpStatus status, String message, Throwable e) {
        super(status, message, e);
    }
}

GlobalErrorAttributes 全局異常屬性值類,代碼如下:

@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {
    
    @Override
    public Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        Map map = super.getErrorAttributes(request, includeStackTrace);
    
        if (getError(request) instanceof GlobalException) {
            GlobalException ex = (GlobalException) getError(request);
            map.put("exception", ex.getClass().getSimpleName());
            map.put("message", ex.getMessage());
            map.put("status", ex.getStatus().value());
            map.put("error", ex.getStatus().getReasonPhrase());
            
            return map;
        }
    
        map.put("exception", "SystemException");
        map.put("message", "System Error , Check logs!");
        map.put("status", "500");
        map.put("error", " System Error ");
        return map;
    }
}

重寫了父類 DefaultErrorAttributes 默認(rèn)錯誤屬性類的 getErrorAttributes 獲取錯誤屬性方法,從服務(wù)請求封裝 ServerRequest 中獲取對應(yīng)的異常。

然后判斷是否是 GlobalException,如果是 CityHandler 服務(wù)處理類拋出的 GlobalException,則返回對應(yīng)的異常的信息。

GlobalErrorWebExceptionHandler 全局異常處理類,代碼如下:

@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext,
            ServerCodecConfigurer serverCodecConfigurer) {
        super(g, new ResourceProperties(), applicationContext);
        super.setMessageWriters(serverCodecConfigurer.getWriters());
        super.setMessageReaders(serverCodecConfigurer.getReaders());
    }

    @Override
    protected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    private Mono renderErrorResponse(final ServerRequest request) {

        final Map errorPropertiesMap = getErrorAttributes(request, false);

        return ServerResponse.status(HttpStatus.BAD_REQUEST)
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .body(BodyInserters.fromObject(errorPropertiesMap));
    }

}

代碼解析如下:

AbstractErrorWebExceptionHandler 抽象類是用來處理全局錯誤時進(jìn)行擴(kuò)展和實現(xiàn)

@Order 注解標(biāo)記 AspectJ 的切面排序,值越小擁有越高的優(yōu)先級,這里設(shè)置優(yōu)先級偏高。

構(gòu)造函數(shù)將 GlobalErrorAttributes 全局異常屬性值類設(shè)置到 AbstractErrorWebExceptionHandler 抽象類的局部變量中。

重寫 getRoutingFunction 方法,設(shè)置對應(yīng)的 RequestPredicates 和 Mono 服務(wù)響應(yīng)對象

將 GlobalErrorAttributes 的全局異常屬性值 map,設(shè)置到新的 ServerResponse 即可。

到此基本結(jié)束。Spring Boot MVC 錯誤碼如何實戰(zhàn),參考地址:https://www.bysocket.com/arch...

2.5 運(yùn)行驗證

在 IDEA 中執(zhí)行 Application 類啟動,任意正常模式或者 Debug 模式。然后打開瀏覽器訪問:

http://localhost:8080/hello

異常界面如下:

圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272

可見,這是在 CityHandler 城市服務(wù)處理類邏輯中拋出的全局異常信息。那么正常情況會是如何?

改下 URL ,訪問如下:

http://localhost:8080/hello?city=WenLing

正常界面如下:

圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272

三、小結(jié)

在 Spring 框架中沒有代表錯誤響應(yīng)的類,只是返回響應(yīng)對象,一個 Map。如果需要定義業(yè)務(wù)的錯誤碼返回體,參考錯誤碼如何實戰(zhàn),參考地址:https://www.bysocket.com/arch...。

本文重點(diǎn)還是有別于 Spring Boot 傳統(tǒng) MVC 模式統(tǒng)一異常處理,實戰(zhàn)了 WebFlux 全局異常處理機(jī)制。實戰(zhàn)中這塊擴(kuò)展需要考慮:

異常分層,從基類中擴(kuò)展出來

錯誤碼設(shè)計分層,易擴(kuò)展,比如在錯誤碼中新增調(diào)用量字段...

代碼示例

本文示例讀者可以通過查看下面?zhèn)}庫的中的模塊工程名: 2-x-spring-boot-webflux-handling-errors:

Github:https://github.com/JeffLi1993/springboot-learning-example

Gitee:https://gitee.com/jeff1993/springboot-learning-example

如果您對這些感興趣,歡迎 star、follow、收藏、轉(zhuǎn)發(fā)給予支持!

參考資料

WebFlux REST API 全局異常處理:https://www.bysocket.com/arch...

https://dzone.com/articles/ex...

以下專題教程也許您會有興趣

《Spring Boot 2.x 系列教程》 https://www.bysocket.com/spri...

《Java 核心系列教程》 https://www.bysocket.com/arch...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74138.html

相關(guān)文章

  • Spring Boot 2 快速教程:WebFlux 快速入門(二)

    摘要:響應(yīng)式編程是基于異步和事件驅(qū)動的非阻塞程序,只是垂直通過在內(nèi)啟動少量線程擴(kuò)展,而不是水平通過集群擴(kuò)展。三特性常用的生產(chǎn)的特性如下響應(yīng)式編程模型適用性內(nèi)嵌容器組件還有對日志消息測試及擴(kuò)展等支持。 摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號:泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載,保留摘要,謝謝! 02:WebFlux 快速入門實踐 文章工程: JDK...

    gaara 評論0 收藏0
  • Spring Boot 2.x 系列教程:WebFlux 系列教程大綱(一)

    摘要:使用則需要及以上版本。開發(fā)使用框架七系列教程目錄系列教程大綱快速入門實踐實踐整合整合中和實踐整合中實現(xiàn)緩存中實現(xiàn)通信集成測試及部署實戰(zhàn)圖書管理系統(tǒng) WebFlux 系列教程大綱 一、背景 大家都知道,Spring Framework 是 Java/Spring 應(yīng)用程序跨平臺開發(fā)框架,也是 Java EE(Java Enterprise Edition) 輕量級框架,其 Spring ...

    jone5679 評論0 收藏0
  • Spring Boot 最流行的 16 條實踐解讀!

    摘要:來源是最流行的用于開發(fā)微服務(wù)的框架。以下依次列出了最佳實踐,排名不分先后。這非常有助于避免可怕的地獄。推薦使用構(gòu)造函數(shù)注入這一條實踐來自的項目負(fù)責(zé)人。保持業(yè)務(wù)邏輯免受代碼侵入的一種方法是使用構(gòu)造函數(shù)注入。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkHQ40ly9Oztiart2lESCyjCH0JwFRp3oErlYobhibM...

    Ethan815 評論0 收藏0
  • 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》

    摘要:下一代服務(wù)端開發(fā)下一代服務(wù)端開發(fā)第部門快速開始第章快速開始環(huán)境準(zhǔn)備,,快速上手實現(xiàn)一個第章企業(yè)級服務(wù)開發(fā)從到語言的缺點(diǎn)發(fā)展歷程的缺點(diǎn)為什么是產(chǎn)生的背景解決了哪些問題為什么是的發(fā)展歷程容器的配置地獄是什么從到下一代企業(yè)級服務(wù)開發(fā)在移動開發(fā)領(lǐng)域 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》 Kotlin + Spring Boot : 下一代 Java...

    springDevBird 評論0 收藏0
  • SpringBoot Kotlin 系列之HTML與WebFlux

    摘要:上一章我們提到過與,對于具體的介紹沒說到,這一章我在這里簡單介紹一下,既然提到和,那肯定得提到什么是響應(yīng)式編程,什么是。 showImg(https://segmentfault.com/img/remote/1460000018819338?w=1024&h=500); 上一章我們提到過Mono 與 Flux,對于具體的介紹沒說到,這一章我在這里簡單介紹一下,既然提到Mono和Flu...

    crossoverJie 評論0 收藏0

發(fā)表評論

0條評論

BicycleWarrior

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<