日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

​SpringCloud:统一异常处理

發布時間:2025/3/20 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ​SpringCloud:统一异常处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今日推薦程序猿慣用口頭禪,你被擊中了嗎? 常見代碼重構技巧(非常實用) B站,牛啊。

程序員缺乏經驗的 7 種表現

2021年4月程序員工資統計:平均14596元,南京程序員收入擠進一線。

作者:BNDong

www.cnblogs.com/bndong/p/10135370.html

在啟動應用時會發現在控制臺打印的日志中出現了兩個路徑為 {[/error]} 的訪問地址,當系統中發送異常錯誤時,Spring Boot 會根據請求方式分別跳轉到以 JSON 格式或以界面顯示的 /error 地址中顯示錯誤信息。

2018-12-18?09:36:24.627??INFO?19040?---?[???????????main]?s.w.s.m.m.a.RequestMappingHandlerMapping?:?Mapped?"{[/error]}"?... 2018-12-18?09:36:24.632??INFO?19040?---?[???????????main]?s.w.s.m.m.a.RequestMappingHandlerMapping?:?Mapped?"{[/error],produces=[text/html]}"?...

默認異常處理

使用 AJAX 方式請求時返回的 JSON 格式錯誤信息。

{"timestamp":?"2018-12-18T01:50:51.196+0000","status":?404,"error":?"Not?Found","message":?"No?handler?found?for?GET?/err404","path":?"/err404" }

使用瀏覽器請求時返回的錯誤信息界面。

自定義異常處理

引入依賴

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId> </dependency>

fastjson 是 JSON 序列化依賴, spring-boot-starter-freemarker 是一個模板引擎,用于我們設置錯誤輸出模板。

增加配置

properties

#?出現錯誤時,?直接拋出異常(便于異常統一處理,否則捕獲不到404) spring.mvc.throw-exception-if-no-handler-found=true #?不要為工程中的資源文件建立映射 spring.resources.add-mappings=false

yml

spring:#?出現錯誤時,?直接拋出異常(便于異常統一處理,否則捕獲不到404)mvc:throw-exception-if-no-handler-found:?true#?不要為工程中的資源文件建立映射resources:add-mappings:?false

新建錯誤信息實體

/***?信息實體*/ public?class?ExceptionEntity?implements?Serializable?{private?static?final?long?serialVersionUID?=?1L;private?String?message;private?int????code;private?String?error;private?String?path;@JSONField(format?=?"yyyy-MM-dd?hh:mm:ss")private?Date?timestamp?=?new?Date();public?static?long?getSerialVersionUID()?{return?serialVersionUID;}public?String?getMessage()?{return?message;}public?void?setMessage(String?message)?{this.message?=?message;}public?int?getCode()?{return?code;}public?void?setCode(int?code)?{this.code?=?code;}public?String?getError()?{return?error;}public?void?setError(String?error)?{this.error?=?error;}public?String?getPath()?{return?path;}public?void?setPath(String?path)?{this.path?=?path;}public?Date?getTimestamp()?{return?timestamp;}public?void?setTimestamp(Date?timestamp)?{this.timestamp?=?timestamp;} }

新建自定義異常

/***?自定義異常*/ public?class?BasicException?extends?RuntimeException?{private?static?final?long?serialVersionUID?=?1L;private?int?code?=?0;public?BasicException(int?code,?String?message)?{super(message);this.code?=?code;}public?int?getCode()?{return?this.code;} } /***?業務異常*/ public?class?BusinessException?extends?BasicException?{private?static?final?long?serialVersionUID?=?1L;public?BusinessException(int?code,?String?message)?{super(code,?message);} }

BasicException 繼承了 RuntimeException ,并在原有的 Message 基礎上增加了錯誤碼 code 的內容。而 BusinessException 則是在業務中具體使用的自定義異常類,起到了對不同的異常信息進行分類的作用。

新建 error.ftl 模板文件

位置:/src/main/resources/templates/ 用于顯示錯誤信息

<!DOCTYPE?html> <html> <head><meta?name="robots"?content="noindex,nofollow"?/><meta?name="viewport"?content="width=device-width,?initial-scale=1,?user-scalable=no"><style>h2{color:?#4288ce;font-weight:?400;padding:?6px?0;margin:?6px?0?0;font-size:?18px;border-bottom:?1px?solid?#eee;}/*?Exception?Variables?*/.exception-var?table{width:?100%;max-width:?500px;margin:?12px?0;box-sizing:?border-box;table-layout:fixed;word-wrap:break-word;}.exception-var?table?caption{text-align:?left;font-size:?16px;font-weight:?bold;padding:?6px?0;}.exception-var?table?caption?small{font-weight:?300;display:?inline-block;margin-left:?10px;color:?#ccc;}.exception-var?table?tbody{font-size:?13px;font-family:?Consolas,"Liberation?Mono",Courier,"微軟雅黑";}.exception-var?table?td{padding:?0?6px;vertical-align:?top;word-break:?break-all;}.exception-var?table?td:first-child{width:?28%;font-weight:?bold;white-space:?nowrap;}.exception-var?table?td?pre{margin:?0;}</style> </head> <body><div?class="exception-var"><h2>Exception?Datas</h2><table><tbody><tr><td>Code</td><td>${(exception.code)!}</td></tr><tr><td>Time</td><td>${(exception.timestamp?datetime)!}</td></tr><tr><td>Path</td><td>${(exception.path)!}</td></tr><tr><td>Exception</td><td>${(exception.error)!}</td></tr><tr><td>Message</td><td>${(exception.message)!}</td></tr></tbody></table> </div> </body> </html>

編寫全局異常控制類

/***?全局異常控制類*/ @ControllerAdvice public?class?GlobalExceptionHandler?{/***?404異常處理*/@ExceptionHandler(value?=?NoHandlerFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND)public?ModelAndView?errorHandler(HttpServletRequest?request,?NoHandlerFoundException?exception,?HttpServletResponse?response)?{return?commonHandler(request,?response,exception.getClass().getSimpleName(),HttpStatus.NOT_FOUND.value(),exception.getMessage());}/***?405異常處理*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public?ModelAndView?errorHandler(HttpServletRequest?request,?HttpRequestMethodNotSupportedException?exception,?HttpServletResponse?response)?{return?commonHandler(request,?response,exception.getClass().getSimpleName(),HttpStatus.METHOD_NOT_ALLOWED.value(),exception.getMessage());}/***?415異常處理*/@ExceptionHandler(HttpMediaTypeNotSupportedException.class)public?ModelAndView?errorHandler(HttpServletRequest?request,?HttpMediaTypeNotSupportedException?exception,?HttpServletResponse?response)?{return?commonHandler(request,?response,exception.getClass().getSimpleName(),HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(),exception.getMessage());}/***?500異常處理*/@ExceptionHandler(value?=?Exception.class)public?ModelAndView?errorHandler?(HttpServletRequest?request,?Exception?exception,?HttpServletResponse?response)?{return?commonHandler(request,?response,exception.getClass().getSimpleName(),HttpStatus.INTERNAL_SERVER_ERROR.value(),exception.getMessage());}/***?業務異常處理*/@ExceptionHandler(value?=?BasicException.class)private?ModelAndView?errorHandler?(HttpServletRequest?request,?BasicException?exception,?HttpServletResponse?response)?{return?commonHandler(request,?response,exception.getClass().getSimpleName(),exception.getCode(),exception.getMessage());}/***?表單驗證異常處理*/@ExceptionHandler(value?=?BindException.class)@ResponseBodypublic?ExceptionEntity?validExceptionHandler(BindException?exception,?HttpServletRequest?request,?HttpServletResponse?response)?{List<FieldError>?fieldErrors?=?exception.getBindingResult().getFieldErrors();Map<String,String>?errors?=?new?HashMap<>();for?(FieldError?error:fieldErrors)?{errors.put(error.getField(),?error.getDefaultMessage());}ExceptionEntity?entity?=?new?ExceptionEntity();entity.setMessage(JSON.toJSONString(errors));entity.setPath(request.getRequestURI());entity.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());entity.setError(exception.getClass().getSimpleName());response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());return?entity;}/***?異常處理數據處理*/private?ModelAndView?commonHandler?(HttpServletRequest?request,?HttpServletResponse?response,String?error,?int?httpCode,?String?message)?{ExceptionEntity?entity?=?new?ExceptionEntity();entity.setPath(request.getRequestURI());entity.setError(error);entity.setCode(httpCode);entity.setMessage(message);return?determineOutput(request,?response,?entity);}/***?異常輸出處理*/private?ModelAndView?determineOutput(HttpServletRequest?request,?HttpServletResponse?response,?ExceptionEntity?entity)?{if?(!(request.getHeader("accept").contains("application/json")||?(request.getHeader("X-Requested-With")?!=?null?&&?request.getHeader("X-Requested-With").contains("XMLHttpRequest"))))?{ModelAndView?modelAndView?=?new?ModelAndView("error");modelAndView.addObject("exception",?entity);return?modelAndView;}?else?{response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());response.setCharacterEncoding("UTF8");response.setHeader("Content-Type",?"application/json");try?{response.getWriter().write(ResultJsonTools.build(ResponseCodeConstant.SYSTEM_ERROR,ResponseMessageConstant.APP_EXCEPTION,JSONObject.parseObject(JSON.toJSONString(entity))));}?catch?(IOException?e)?{e.printStackTrace();}return?null;}} }

@ControllerAdvice

作用于類上,用于標識該類用于處理全局異常。

@ExceptionHandler

作用于方法上,用于對攔截的異常類型進行處理。value 屬性用于指定具體的攔截異常類型,如果有多個 ExceptionHandler 存在,則需要指定不同的 value 類型,由于異常類擁有繼承關系,所以 ExceptionHandler 會首先執行在繼承樹中靠前的異常類型。

BindException

該異常來自于表單驗證框架 Hibernate validation,當字段驗證未通過時會拋出此異常。

編寫測試 Controller

@RestController public?class?TestController?{@RequestMapping(value?=?"err")public?void?error(){throw?new?BusinessException(400,?"業務異常錯誤信息");}@RequestMapping(value?=?"err2")public?void?error2(){throw?new?NullPointerException("手動拋出異常信息");}@RequestMapping(value?=?"err3")public?int?error3(){int?a?=?10?/?0;return?a;} }

使用 AJAX 方式請求時返回的 JSON 格式錯誤信息。

#?/err {"msg":?"應用程序異常","code":?-1,"status_code":?0,"data":?{"path":?"/err","code":?400,"error":?"BusinessException","message":?"業務異常錯誤信息","timestamp":?"2018-12-18?11:09:00"} }#?/err2 {"msg":?"應用程序異常","code":?-1,"status_code":?0,"data":?{"path":?"/err2","code":?500,"error":?"NullPointerException","message":?"手動拋出異常信息","timestamp":?"2018-12-18?11:15:15"} }#?/err3 {"msg":?"應用程序異常","code":?-1,"status_code":?0,"data":?{"path":?"/err3","code":?500,"error":?"ArithmeticException","message":?"/?by?zero","timestamp":?"2018-12-18?11:15:46"} }#?/err404 {"msg":?"應用程序異常","code":?-1,"status_code":?0,"data":?{"path":?"/err404","code":?404,"error":?"NoHandlerFoundException","message":?"No?handler?found?for?GET?/err404","timestamp":?"2018-12-18?11:16:11"} }

使用瀏覽器請求時返回的錯誤信息界面。

示例代碼:https://github.com/BNDong/spring-cloud-examples/tree/master/spring-cloud-zuul/cloud-zuul

參考資料

《微服務 分布式架構開發實戰》 龔鵬 著

https://www.jianshu.com/p/1a49fa436623

推薦文章
  • 2021年4月程序員工資統計:平均14596元,南京程序員收入擠進一線。

  • 常見的SQL面試題:經典50例

  • 47K Star 的SpringBoot+MyBatis+docker電商項目,附帶超詳細的文檔!

  • 寫博客能月入10K?

  • 一款基于 Spring Boot 的現代化社區(論壇/問答/社交網絡/博客)

更多項目源碼
  • 這或許是最美的Vue+Element開源后臺管理UI

  • 推薦一款高顏值的 Spring Boot 快速開發框架

  • 一款基于 Spring Boot 的現代化社區(論壇/問答/社交網絡/博客)

  • 13K點贊都基于 Vue+Spring 前后端分離管理系統ELAdmin,大愛

  • 想接私活時薪再翻一倍,建議根據這幾個開源的SpringBoot

總結

以上是生活随笔為你收集整理的​SpringCloud:统一异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。