springBoot 全局異常方式處理自定義異常 @RestControllerAdvice + @ExceptionHandler


前言

     本文講解使用 @ControllerAdvice + @ExceptionHandler 進行全局的 Controller 層異常處理,可以處理大部分開發中用到的自自定義業務異常處理了,再也不用在 Controller 層進行 try-catch 了
     代碼示例地址(代碼里面類名稍微有些不同): https://gitee.com/coderLOL/springboot-demos

一、處理思路

  1. 思路:在sevice業務邏輯層 try{}catch(){} 捕獲拋出,經由contorller 層拋到 自定義全局處理類 中處理自定義異常及系統異常。

     2、實現方式:使用 @RestControllerAdvice + @ExceptionHandler 注解方式實現全局異常處

二、實現過程

 1、@ControllerAdvice 注解定義全局異常處理類 ,@ExceptionHandler 注解聲明異常處        理方法。

     ( 本類方法中用到的 ResponseResultUtil 工具類, ResponseCodeEnum 枚舉類,下面步驟中會介紹)

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @author 路飛 * @date 2018-8-21 * @description 全局異常處理: 使用 @RestControllerAdvice + @ExceptionHandler 注解方式實現全 * 局異常處理 */ @RestControllerAdvice public class GlobalExceptionHandler { private final Logger logger = LogManager.getLogger(GlobalExceptionHandler.class); /** * @author 路飛 * @date 2018-8-22 * @param e 異常 * @description 處理所有不可知的異常 */ @ExceptionHandler({Exception.class}) //申明捕獲那個異常類 public ResponseResultVO globalExceptionHandler(Exception e) { this.logger.error(e.getMessage(), e); return new ResponseResultUtil().error(ResponseCodeEnum.OPERATE_FAIL); } /** * @author 路飛 * @date 2018-8-21 * @param e 異常 * @description 處理所有業務異常 */ @ExceptionHandler({BaseBusinessException.class}) public ResponseResultVO BusinessExceptionHandler(BaseBusinessException e) { this.logger.error(e); return new ResponseResultUtil().error(e.getCode(), e.getMessage()); } }

2、定義一個用於返回頁面結果信息的VO對象類:ResponseResultVO

/** * @author 路飛 * @date 2018-8-21 * @description 請求響應對象 */ public final class ResponseResultVO<T> { /** * @description 響應碼 */ private int code; /** * @description 響應消息 */ private String message; /** * @description 分頁對象 (如果用不到,這個可以不寫) */ private PageVO page; /** * @description 數據 */ private Object data; public final int getCode() { return this.code; } public final void setCode(int code) { this.code = code; } public final String getMessage() { return this.message; } public final void setMessage( String message) { this.message = message; } public final PageVO getPage() { return this.page; } public final void setPage( PageVO page) { this.page = page; } public final Object getData() { return this.data; } public final void setData(Object data) { this.data = data; } public ResponseResultVO(int code, String message, PageVO page, Object data) { super(); this.code = code; this.message = message; this.page = page; this.data = data; } }

3、 定義一個對步驟2中 返回信息結果處理的工具類:ResponseResultUtil

/** * @author zhangwenlong * @date 2018-8-20 * @description 請求響應工具類 */ public final class ResponseResultUtil { /** * @param code 響應碼 * @param message 相應信息 * @param any 返回的數據 * @description 請求成功返回對象 */ public final ResponseResultVO success(int code, String message, PageVO page, Object any) { return new ResponseResultVO(code, message, page, any); } /** * @param any 返回的數據 * @description 請求成功返回對象 */ public final ResponseResultVO success(Object any) { int code = ResponseCodeEnum.SUCCESS.getCode(); String message = ResponseCodeEnum.SUCCESS.getMessage(); return this.success(code, message, null, any); } /** * @param any 返回的數據 * @description 請求成功返回對象 */ public final ResponseResultVO success(Object any, PageVO page) { int code = ResponseCodeEnum.SUCCESS.getCode(); String message = ResponseCodeEnum.SUCCESS.getMessage(); return this.success(code, message, page, any); } /** * @description 請求成功返回對象 */ public final ResponseResultVO success() { return this.success(null); } /** * @param responseCode 返回的響應碼所對應的枚舉類 * @description 請求失敗返回對象 */ public final ResponseResultVO error(ResponseCodeEnum responseCode) { return new ResponseResultVO(responseCode.getCode(), responseCode.getMessage(), null, null); } /** * @param code 響應碼 * @param message 相應信息 * @description 請求失敗返回對象 */ public final ResponseResultVO error(int code, String message) { return new ResponseResultVO(code, message, null, null); } }

4、為方便統一管理異常代碼和信息之間的關系,建立枚舉類: ResponseCodeEnum

/** * @author 路飛 * @date 2018-8-20 * @description 響應碼配置枚舉 */ public enum ResponseCodeEnum { // 系統通用 SUCCESS(200, "操作成功"), UNLOGIN_ERROR(233, "沒有登錄"), OPERATE_FAIL(666, "操作失敗"), // 用戶 SAVE_USER_INFO_FAILED(2001, "保存用戶信息失敗"), GET_USER_INFO_FAILED(2002, "保存用戶信息失敗"), WECHAT_VALID_FAILED(2003, "微信驗證失敗"), GET_USER_AUTH_INFO_FAILED(2004, "根據條件獲取用戶授權信息失敗"), SAVE_USER_AUTH_INFO_FAILED(2005, "保存用戶授權失敗"); private Integer code; private String message; ResponseCodeEnum(Integer code, String message) { this.code = code; this.message = message; } public final Integer getCode() { return this.code; } public final String getMessage() { return this.message; } }

5、 

(1)封裝一個基礎業務異常類(讓所有自定義業務異常類 繼承此 基礎類):BaseBusinessException

/** * @author zhangwenlong * @date 2018-8-21 * @description 價值分析系統所有的 業務異常父類 */ public class BaseBusinessException extends RuntimeException { private Integer code; // 給子類用的方法 public BaseBusinessException(ResponseCodeEnum responseCodeEnum) { this(responseCodeEnum.getMessage(), responseCodeEnum.getCode()); } private BaseBusinessException(String message, Integer code) { super(message); this.code = code; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } }

(2)自定義的業務異常類 (例如):

              自定義用戶異常

/** * @author 路費 * @date 2018-8-21 * @description 自定義用戶異常 */ public class UserException extends BaseBusinessException { // 繼承繼承 業務異常類 public UserException(ResponseCodeEnum responseCodeEnum) { super(responseCodeEnum); } }

6、service 層拋出

/** * @author 路飛 * @date 2018-8-21 * @description 用戶信息業務接口實現類 */ @Service("userInfoService") public class UserInfoSerimpl implements UserInfoService { private Logger logger = LoggerFactory.getLogger(UserInfoSerimpl.class); @Resource private UserInfoMapper userInfoMapper; // maybatis通用Mapper插件 /** * @author 路飛 * @date 2018-8-21 * @param userInfo 用戶信息 * @description 保存用戶信息 */ @Override public void saveUserInfo(UserInfo userInfo) { try { userInfoMapper.insertSelective(userInfo); } catch (Exception e) { logger.error("獲取用戶信息失敗", e); //拋出自定義異常: ResponseCodeEnum.SAVE_USER_INFO_FAILED throw new UserException(ResponseCodeEnum.SAVE_USER_INFO_FAILED); } } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM