摘要:挺多人咨詢的,異常處理用切面注解去實(shí)現(xiàn)去全局異常處理。全局異常處理類,代碼如下代碼解析如下抽象類是用來處理全局錯(cuò)誤時(shí)進(jìn)行擴(kuò)展和實(shí)現(xiàn)注解標(biāo)記的切面排序,值越小擁有越高的優(yōu)先級(jí),這里設(shè)置優(yōu)先級(jí)偏高。
本文內(nèi)容
為什么要全局異常處理?
WebFlux REST 全局異常處理實(shí)戰(zhàn)
小結(jié)
摘錄:只有不斷培養(yǎng)好習(xí)慣,同時(shí)不斷打破壞習(xí)慣,我們的行為舉止才能夠自始至終都是正確的。一、為什么要全局異常處理?
前后端分離開發(fā),一般提供 REST API,正常返回會(huì)有響應(yīng)體,異常情況下會(huì)有對(duì)應(yīng)的錯(cuò)誤碼響應(yīng)。
挺多人咨詢的,Spring Boot MVC 異常處理用切面 @RestControllerAdvice 注解去實(shí)現(xiàn)去全局異常處理。那 WebFlux 如何處理異常?如何實(shí)現(xiàn)統(tǒng)一錯(cuò)誤碼異常處理?
全局異常處理的好處:
異常錯(cuò)誤碼等統(tǒng)一維護(hù)
避免一些重復(fù)代碼
二、WebFlux REST 全局異常處理實(shí)戰(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)用啟動(dòng)類,是可以用來啟動(dòng) Spring Boot 應(yīng)用。其包含了 @SpringBootApplication 注解和 SpringApplication 類,并調(diào)用 SpringApplication 類的 run() 方法,就可以啟動(dòng)該應(yīng)用。
具體實(shí)現(xiàn)類的關(guān)系圖如下:
圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272
2.2 CityRouter 路由器類城市路由器代碼如下:
@Configuration public class CityRouter { @Bean public RouterFunctionrouteCity(CityHandler cityHandler) { return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity); } }
RouterFunctions 對(duì)請(qǐng)求路由處理類,即將請(qǐng)求路由到處理器,這將一個(gè) GET 請(qǐng)求 /hello 路由到處理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 類似。
RouterFunctions.route(RequestPredicate, HandlerFunction) 方法,對(duì)應(yīng)的 參是請(qǐng)求參數(shù)和處理函數(shù),如果請(qǐng)求匹配,就調(diào) 對(duì)應(yīng)的處理器函數(shù)。
2.3 CityHandler 服務(wù)處理類城市服務(wù)器處理類,代碼如下:
@Component public class CityHandler { public MonohelloCity(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:實(shí)現(xiàn)發(fā)布者,并返回 0 或 1 個(gè)元素,即單對(duì)象。Mono 是響應(yīng)流 Publisher 具有基礎(chǔ) rx 操作符。可以成功發(fā)布元素或者錯(cuò)誤。用 Mono 作為返回對(duì)象,是因?yàn)榉祷匕艘粋€(gè) ServerResponse 對(duì)象,而不是多個(gè)元素。
ServerResponse 是對(duì)響應(yīng)的封裝,可以設(shè)置響應(yīng)狀態(tài),響應(yīng)頭,響應(yīng)正文。比如 ok 代表的是 200 響應(yīng)碼、MediaType 枚舉是代表這文本內(nèi)容類型、返回的是 String 的對(duì)象。
ServerRequest 是對(duì)請(qǐng)求的封裝。從請(qǐng)求中拿出 city 的值,如果沒有的話則拋出對(duì)應(yīng)的異常。GlobalException 是封裝的全局異常。
Mono.justOrEmpty():從一個(gè) Optional 對(duì)象或 null 對(duì)象中創(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 MapgetErrorAttributes(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)錯(cuò)誤屬性類的 getErrorAttributes 獲取錯(cuò)誤屬性方法,從服務(wù)請(qǐng)求封裝 ServerRequest 中獲取對(duì)應(yīng)的異常。
然后判斷是否是 GlobalException,如果是 CityHandler 服務(wù)處理類拋出的 GlobalException,則返回對(duì)應(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 RouterFunctiongetRoutingFunction(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 抽象類是用來處理全局錯(cuò)誤時(shí)進(jìn)行擴(kuò)展和實(shí)現(xiàn)
@Order 注解標(biāo)記 AspectJ 的切面排序,值越小擁有越高的優(yōu)先級(jí),這里設(shè)置優(yōu)先級(jí)偏高。
構(gòu)造函數(shù)將 GlobalErrorAttributes 全局異常屬性值類設(shè)置到 AbstractErrorWebExceptionHandler 抽象類的局部變量中。
重寫 getRoutingFunction 方法,設(shè)置對(duì)應(yīng)的 RequestPredicates 和 Mono
將 GlobalErrorAttributes 的全局異常屬性值 map,設(shè)置到新的 ServerResponse 即可。
到此基本結(jié)束。Spring Boot MVC 錯(cuò)誤碼如何實(shí)戰(zhàn),參考地址:https://www.bysocket.com/arch...
2.5 運(yùn)行驗(yàn)證在 IDEA 中執(zhí)行 Application 類啟動(dòng),任意正常模式或者 Debug 模式。然后打開瀏覽器訪問:
http://localhost:8080/hello
異常界面如下:
圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272
可見,這是在 CityHandler 城市服務(wù)處理類邏輯中拋出的全局異常信息。那么正常情況會(huì)是如何?
改下 URL ,訪問如下:
http://localhost:8080/hello?city=WenLing
正常界面如下:
圖片上傳失敗,見原文 https://www.bysocket.com/archives/2272
三、小結(jié)在 Spring 框架中沒有代表錯(cuò)誤響應(yīng)的類,只是返回響應(yīng)對(duì)象,一個(gè) Map。如果需要定義業(yè)務(wù)的錯(cuò)誤碼返回體,參考錯(cuò)誤碼如何實(shí)戰(zhàn),參考地址:https://www.bysocket.com/arch...。
本文重點(diǎn)還是有別于 Spring Boot 傳統(tǒng) MVC 模式統(tǒng)一異常處理,實(shí)戰(zhàn)了 WebFlux 全局異常處理機(jī)制。實(shí)戰(zhàn)中這塊擴(kuò)展需要考慮:
異常分層,從基類中擴(kuò)展出來
錯(cuò)誤碼設(shè)計(jì)分層,易擴(kuò)展,比如在錯(cuò)誤碼中新增調(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
如果您對(duì)這些感興趣,歡迎 star、follow、收藏、轉(zhuǎn)發(fā)給予支持!
參考資料WebFlux REST API 全局異常處理:https://www.bysocket.com/arch...
https://dzone.com/articles/ex...
以下專題教程也許您會(huì)有興趣《Spring Boot 2.x 系列教程》 https://www.bysocket.com/spri...
《Java 核心系列教程》 https://www.bysocket.com/arch...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/74138.html
摘要:響應(yīng)式編程是基于異步和事件驅(qū)動(dòng)的非阻塞程序,只是垂直通過在內(nèi)啟動(dòng)少量線程擴(kuò)展,而不是水平通過集群擴(kuò)展。三特性常用的生產(chǎn)的特性如下響應(yīng)式編程模型適用性內(nèi)嵌容器組件還有對(duì)日志消息測試及擴(kuò)展等支持。 摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號(hào):泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載,保留摘要,謝謝! 02:WebFlux 快速入門實(shí)踐 文章工程: JDK...
摘要:使用則需要及以上版本。開發(fā)使用框架七系列教程目錄系列教程大綱快速入門實(shí)踐實(shí)踐整合整合中和實(shí)踐整合中實(shí)現(xiàn)緩存中實(shí)現(xiàn)通信集成測試及部署實(shí)戰(zhàn)圖書管理系統(tǒng) WebFlux 系列教程大綱 一、背景 大家都知道,Spring Framework 是 Java/Spring 應(yīng)用程序跨平臺(tái)開發(fā)框架,也是 Java EE(Java Enterprise Edition) 輕量級(jí)框架,其 Spring ...
摘要:來源是最流行的用于開發(fā)微服務(wù)的框架。以下依次列出了最佳實(shí)踐,排名不分先后。這非常有助于避免可怕的地獄。推薦使用構(gòu)造函數(shù)注入這一條實(shí)踐來自的項(xiàng)目負(fù)責(zé)人。保持業(yè)務(wù)邏輯免受代碼侵入的一種方法是使用構(gòu)造函數(shù)注入。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkHQ40ly9Oztiart2lESCyjCH0JwFRp3oErlYobhibM...
摘要:下一代服務(wù)端開發(fā)下一代服務(wù)端開發(fā)第部門快速開始第章快速開始環(huán)境準(zhǔn)備,,快速上手實(shí)現(xiàn)一個(gè)第章企業(yè)級(jí)服務(wù)開發(fā)從到語言的缺點(diǎn)發(fā)展歷程的缺點(diǎn)為什么是產(chǎn)生的背景解決了哪些問題為什么是的發(fā)展歷程容器的配置地獄是什么從到下一代企業(yè)級(jí)服務(wù)開發(fā)在移動(dòng)開發(fā)領(lǐng)域 《 Kotlin + Spring Boot : 下一代 Java 服務(wù)端開發(fā) 》 Kotlin + Spring Boot : 下一代 Java...
摘要:上一章我們提到過與,對(duì)于具體的介紹沒說到,這一章我在這里簡單介紹一下,既然提到和,那肯定得提到什么是響應(yīng)式編程,什么是。 showImg(https://segmentfault.com/img/remote/1460000018819338?w=1024&h=500); 上一章我們提到過Mono 與 Flux,對(duì)于具體的介紹沒說到,這一章我在這里簡單介紹一下,既然提到Mono和Flu...
閱讀 1883·2021-09-28 09:36
閱讀 2435·2021-09-08 09:35
閱讀 3074·2019-08-30 15:53
閱讀 1561·2019-08-30 14:08
閱讀 673·2019-08-29 18:40
閱讀 2849·2019-08-29 13:57
閱讀 2711·2019-08-29 13:55
閱讀 690·2019-08-26 13:45