SpringBoot項(xiàng)目?jī)?yōu)雅的全局異常處理方式(全網(wǎng)最新)
前言
在日常項(xiàng)目開發(fā)中,異常是常見的,但是如何更高效的處理好異常信息,讓我們能快速定位到BUG,是很重要的,不僅能夠提高我們的開發(fā)效率,還能讓你代碼看上去更舒服,SpringBoot的項(xiàng)目已經(jīng)對(duì)有一定的異常處理了,但是對(duì)于我們開發(fā)者而言可能就不太合適了,因此我們需要對(duì)這些異常進(jìn)行統(tǒng)一的捕獲并處理。
一、全局異常處理方式一
SpringBoot中,@ControllerAdvice 即可開啟全局異常處理,使用該注解表示開啟了全局異常的捕獲,我們只需在自定義一個(gè)方法使用@ExceptionHandler注解然后定義捕獲異常的類型即可對(duì)這些捕獲的異常進(jìn)行統(tǒng)一的處理。
1.1 自定義全局異常類
/** * @description: 自定義異常處理 * @author: DT * @date: 2021/4/19 21:17 * @version: v1.0 */ @ControllerAdvice public class MyExceptionHandler { @ExceptionHandler(value =Exception.class) @ResponseBody public String exceptionHandler(Exception e){ System.out.println("全局異常捕獲>>>:"+e); return "全局異常捕獲,錯(cuò)誤原因>>>"+e.getMessage(); } }
1.2 手動(dòng)拋出異常
@GetMapping("/getById/{userId}") public CommonResult<User> getById(@PathVariable Integer userId){ // 手動(dòng)拋出異常 int a = 10/0; return CommonResult.success(userService.getById(userId)); }
1.3 測(cè)試打印
很顯然這樣的用戶體驗(yàn)效果是極差的,雖然這種能夠讓我們知道異常的原因,但是在很多的情況下來說,可能還是不夠人性化,不符合我們的要求。
二、全局異常處理方式二
2.1 定義基礎(chǔ)接口類
/** * @description: 服務(wù)接口類 * @author: DT * @date: 2021/4/19 21:39 */ public interface BaseErrorInfoInterface { /** * 錯(cuò)誤碼 * @return */ String getResultCode(); /** * 錯(cuò)誤描述 * @return */ String getResultMsg(); }
2.2 定義枚舉類
/** * @description: 異常處理枚舉類 * @author: DT * @date: 2021/4/19 21:41 * @version: v1.0 */ public enum ExceptionEnum implements BaseErrorInfoInterface{ // 數(shù)據(jù)操作錯(cuò)誤定義 SUCCESS("2000", "成功!"), BODY_NOT_MATCH("4000","請(qǐng)求的數(shù)據(jù)格式不符!"), SIGNATURE_NOT_MATCH("4001","請(qǐng)求的數(shù)字簽名不匹配!"), NOT_FOUND("4004", "未找到該資源!"), INTERNAL_SERVER_ERROR("5000", "服務(wù)器內(nèi)部錯(cuò)誤!"), SERVER_BUSY("5003","服務(wù)器正忙,請(qǐng)稍后再試!"); /** * 錯(cuò)誤碼 */ private final String resultCode; /** * 錯(cuò)誤描述 */ private final String resultMsg; ExceptionEnum(String resultCode, String resultMsg) { this.resultCode = resultCode; this.resultMsg = resultMsg; } @Override public String getResultCode() { return resultCode; } @Override public String getResultMsg() { return resultMsg; } }
2.3 自定義異常類
/** * @description: 自定義異常類 * @author: DT * @date: 2021/4/19 21:44 * @version: v1.0 */ public class BizException extends RuntimeException{ private static final long serialVersionUID = 1L; /** * 錯(cuò)誤碼 */ protected String errorCode; /** * 錯(cuò)誤信息 */ protected String errorMsg; public BizException() { super(); } public BizException(BaseErrorInfoInterface errorInfoInterface) { super(errorInfoInterface.getResultCode()); this.errorCode = errorInfoInterface.getResultCode(); this.errorMsg = errorInfoInterface.getResultMsg(); } public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) { super(errorInfoInterface.getResultCode(), cause); this.errorCode = errorInfoInterface.getResultCode(); this.errorMsg = errorInfoInterface.getResultMsg(); } public BizException(String errorMsg) { super(errorMsg); this.errorMsg = errorMsg; } public BizException(String errorCode, String errorMsg) { super(errorCode); this.errorCode = errorCode; this.errorMsg = errorMsg; } public BizException(String errorCode, String errorMsg, Throwable cause) { super(errorCode, cause); this.errorCode = errorCode; this.errorMsg = errorMsg; } public String getErrorCode() { return errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } @Override public Throwable fillInStackTrace() { return this; } }
2.4 自定義數(shù)據(jù)傳輸
/** * @description: 自定義數(shù)據(jù)傳輸 * @author: DT * @date: 2021/4/19 21:47 * @version: v1.0 */ public class ResultResponse { /** * 響應(yīng)代碼 */ private String code; /** * 響應(yīng)消息 */ private String message; /** * 響應(yīng)結(jié)果 */ private Object result; public ResultResponse() { } public ResultResponse(BaseErrorInfoInterface errorInfo) { this.code = errorInfo.getResultCode(); this.message = errorInfo.getResultMsg(); } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } /** * 成功 * * @return */ public static ResultResponse success() { return success(null); } /** * 成功 * @param data * @return */ public static ResultResponse success(Object data) { ResultResponse rb = new ResultResponse(); rb.setCode(ExceptionEnum.SUCCESS.getResultCode()); rb.setMessage(ExceptionEnum.SUCCESS.getResultMsg()); rb.setResult(data); return rb; } /** * 失敗 */ public static ResultResponse error(BaseErrorInfoInterface errorInfo) { ResultResponse rb = new ResultResponse(); rb.setCode(errorInfo.getResultCode()); rb.setMessage(errorInfo.getResultMsg()); rb.setResult(null); return rb; } /** * 失敗 */ public static ResultResponse error(String code, String message) { ResultResponse rb = new ResultResponse(); rb.setCode(code); rb.setMessage(message); rb.setResult(null); return rb; } /** * 失敗 */ public static ResultResponse error( String message) { ResultResponse rb = new ResultResponse(); rb.setCode("-1"); rb.setMessage(message); rb.setResult(null); return rb; } @Override public String toString() { return JSONObject.toJSONString(this); } }
2.5 自定義全局異常處理
/** * @description: 自定義異常處理 * @author: DT * @date: 2021/4/19 21:51 * @version: v1.0 */ @ControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); /** * 處理自定義的業(yè)務(wù)異常 * @param req * @param e * @return */ @ExceptionHandler(value = BizException.class) @ResponseBody public ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e){ logger.error("發(fā)生業(yè)務(wù)異常!原因是:{}",e.getErrorMsg()); return ResultResponse.error(e.getErrorCode(),e.getErrorMsg()); } /** * 處理空指針的異常 * @param req * @param e * @return */ @ExceptionHandler(value =NullPointerException.class) @ResponseBody public ResultResponse exceptionHandler(HttpServletRequest req, NullPointerException e){ logger.error("發(fā)生空指針異常!原因是:",e); return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH); } /** * 處理其他異常 * @param req * @param e * @return */ @ExceptionHandler(value =Exception.class) @ResponseBody public ResultResponse exceptionHandler(HttpServletRequest req, Exception e){ logger.error("未知異常!原因是:",e); return ResultResponse.error(ExceptionEnum.INTERNAL_SERVER_ERROR); } }
2.6 測(cè)試代碼
@PostMapping("/add") public boolean add(@RequestBody User user) { //如果姓名為空就手動(dòng)拋出一個(gè)自定義的異常! if(user.getName()==null){ throw new BizException("-1","用戶姓名不能為空!"); } return true; }
@PutMapping("/update") public boolean update(@RequestBody User user) { //這里故意造成一個(gè)空指針的異常,并且不進(jìn)行處理 String str = null; str.equals("111"); return true; }
@DeleteMapping("/delete") public boolean delete(@RequestBody User user) { //這里故意造成一個(gè)異常,并且不進(jìn)行處理 Integer.parseInt("abc123"); return true; }
如果我們想捕獲這個(gè)類型轉(zhuǎn)換異常,是不是再添加一個(gè)遺產(chǎn)處理方法就可了。
/** * 處理類型轉(zhuǎn)換異常 * @param req * @param e * @return */ @ExceptionHandler(value = NumberFormatException.class) @ResponseBody public ResultResponse exceptionHandler(HttpServletRequest req, NumberFormatException e){ logger.error("發(fā)生類型轉(zhuǎn)換異常!原因是:",e); return ResultResponse.error(ExceptionEnum.PARAMS_NOT_CONVERT); }
PARAMS_NOT_CONVERT("4002","類型轉(zhuǎn)換不對(duì)!"),
自定義全局異常處理除了可以處理上述的數(shù)據(jù)格式之外,也可以處理頁面的跳轉(zhuǎn),只需在新增的異常方法的返回處理上填寫該跳轉(zhuǎn)的路徑并不使用ResponseBody 注解即可。
總結(jié)
異常處理,能夠減少代碼的重復(fù)度和復(fù)雜度,有利于代碼的維護(hù),并且能夠快速定位到BUG,大大提高我們的開發(fā)效率。
到此這篇關(guān)于SpringBoot項(xiàng)目?jī)?yōu)雅的全局異常處理方式(全網(wǎng)最新)的文章就介紹到這了,更多相關(guān)SpringBoot 全局異常處理 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Maven 搭建SpringMVC+Hibernate項(xiàng)目詳解
本文主要介紹Maven 搭建SpringMVC+Hibernate的知識(shí),這里整理了詳細(xì)的資料,并附示例代碼,有興趣的小伙伴可以參考下2016-09-09IDEA搭建配置Java?Web項(xiàng)目的詳細(xì)步驟
這篇文章詳細(xì)介紹了如何使用IDEA創(chuàng)建和配置JavaWeb項(xiàng)目,包括項(xiàng)目結(jié)構(gòu)設(shè)置、WEB-INF目錄和jsp文件的創(chuàng)建,以及Tomcat的配置,是Java初學(xué)者的實(shí)用指南,需要的朋友可以參考下2024-10-10SpringMVC五種類型參數(shù)傳遞及json傳遞參數(shù)
本文主要介紹了SpringMVC五種類型參數(shù)傳遞及json傳遞參數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07java使用socket實(shí)現(xiàn)一個(gè)多線程web服務(wù)器的方法
今天小編就為大家分享一篇java使用socket實(shí)現(xiàn)一個(gè)多線程web服務(wù)器的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10面試官:java ThreadLocal真的會(huì)造成內(nèi)存泄露嗎
ThreadLocal,java面試過程中的“釘子戶”,在網(wǎng)上也充斥著各種有關(guān)ThreadLocal內(nèi)存泄露的問題,本文換個(gè)角度,先思考ThreadLocal體系中的ThreadLocalMap為什么要設(shè)計(jì)成弱引用2021-08-08Spring?Boot使用Schedule實(shí)現(xiàn)定時(shí)任務(wù)的方法
這篇文章主要介紹了Spring?Boot使用Schedule實(shí)現(xiàn)定時(shí)任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03