全域例外處理
- 前言
- 一、全域例外處理方式一
- 1.1 自定義全域例外類
- 1.2 手動拋出例外
- 1.3 測驗列印
- 二、全域例外處理方式二
- 2.1 定義基礎介面類
- 2.2 定義列舉類
- 2.3 自定義例外類
- 2.4 自定義資料傳輸
- 2.5 自定義全域例外處理
- 2.6 測驗代碼
- 總結
前言
在日常專案開發中,例外是常見的,但是如何更高效的處理好例外資訊,讓我們能快速定位到BUG,是很重要的,不僅能夠提高我們的開發效率,還能讓你代碼看上去更舒服,SpringBoot的專案已經對有一定的例外處理了,但是對于我們開發者而言可能就不太合適了,因此我們需要對這些例外進行統一的捕獲并處理,
一、全域例外處理方式一
SpringBoot中,@ControllerAdvice 即可開啟全域例外處理,使用該注解表示開啟了全域例外的捕獲,我們只需在自定義一個方法使用@ExceptionHandler注解然后定義捕獲例外的型別即可對這些捕獲的例外進行統一的處理,
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 "全域例外捕獲,錯誤原因>>>"+e.getMessage();
}
}
1.2 手動拋出例外
@GetMapping("/getById/{userId}")
public CommonResult<User> getById(@PathVariable Integer userId){
// 手動拋出例外
int a = 10/0;
return CommonResult.success(userService.getById(userId));
}
1.3 測驗列印


很顯然這樣的用戶體驗效果是極差的,雖然這種能夠讓我們知道例外的原因,但是在很多的情況下來說,可能還是不夠人性化,不符合我們的要求,
二、全域例外處理方式二
2.1 定義基礎介面類
/**
* @description: 服務介面類
* @author: DT
* @date: 2021/4/19 21:39
*/
public interface BaseErrorInfoInterface {
/**
* 錯誤碼
* @return
*/
String getResultCode();
/**
* 錯誤描述
* @return
*/
String getResultMsg();
}
2.2 定義列舉類
/**
* @description: 例外處理列舉類
* @author: DT
* @date: 2021/4/19 21:41
* @version: v1.0
*/
public enum ExceptionEnum implements BaseErrorInfoInterface{
// 資料操作錯誤定義
SUCCESS("2000", "成功!"),
BODY_NOT_MATCH("4000","請求的資料格式不符!"),
SIGNATURE_NOT_MATCH("4001","請求的數字簽名不匹配!"),
NOT_FOUND("4004", "未找到該資源!"),
INTERNAL_SERVER_ERROR("5000", "服務器內部錯誤!"),
SERVER_BUSY("5003","服務器正忙,請稍后再試!");
/**
* 錯誤碼
*/
private final String resultCode;
/**
* 錯誤描述
*/
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;
/**
* 錯誤碼
*/
protected String errorCode;
/**
* 錯誤資訊
*/
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 自定義資料傳輸
/**
* @description: 自定義資料傳輸
* @author: DT
* @date: 2021/4/19 21:47
* @version: v1.0
*/
public class ResultResponse {
/**
* 回應代碼
*/
private String code;
/**
* 回應訊息
*/
private String message;
/**
* 回應結果
*/
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);
/**
* 處理自定義的業務例外
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e){
logger.error("發生業務例外!原因是:{}",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("發生空指標例外!原因是:",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 測驗代碼
@PostMapping("/add")
public boolean add(@RequestBody User user) {
//如果姓名為空就手動拋出一個自定義的例外!
if(user.getName()==null){
throw new BizException("-1","用戶姓名不能為空!");
}
return true;
}

@PutMapping("/update")
public boolean update(@RequestBody User user) {
//這里故意造成一個空指標的例外,并且不進行處理
String str = null;
str.equals("111");
return true;
}

@DeleteMapping("/delete")
public boolean delete(@RequestBody User user) {
//這里故意造成一個例外,并且不進行處理
Integer.parseInt("abc123");
return true;
}

如果我們想捕獲這個型別轉換例外,是不是再添加一個遺產處理方法就可了,

/**
* 處理型別轉換例外
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = NumberFormatException.class)
@ResponseBody
public ResultResponse exceptionHandler(HttpServletRequest req, NumberFormatException e){
logger.error("發生型別轉換例外!原因是:",e);
return ResultResponse.error(ExceptionEnum.PARAMS_NOT_CONVERT);
}
PARAMS_NOT_CONVERT("4002","型別轉換不對!"),

自定義全域例外處理除了可以處理上述的資料格式之外,也可以處理頁面的跳轉,只需在新增的例外方法的回傳處理上填寫該跳轉的路徑并不使用ResponseBody 注解即可,
總結
例外處理,能夠減少代碼的重復度和復雜度,有利于代碼的維護,并且能夠快速定位到BUG,大大提高我們的開發效率,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/278456.html
標籤:java
上一篇:Java實作冒泡排序(詳解)
