使用全局异常来避免冗余的代码:
使用全局异常前:
controller层通篇的try-catch以及大量重复的代码来捕获在service层抛出的异常
使用全局异常后:
只需要增加一个全局异常类,里面设置好要捕获的异常以及处理方式,就可以了,针对不通用的异常处理可以使用try-catch
全局异常设置:
package cn.test.account.handler;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import cn.test.account.domain.ReturnCode;
import cn.test.account.exceptions.BusinessException;
import cn.test.account.model.response.CodeResponse;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(BusinessException.class)
public ResponseEntity<?> handleBusinessException(BusinessException ex) {
CodeResponse idResponse = new CodeResponse();
idResponse.setCode(ex.getCode());
idResponse.setMessage(ex.getMessage());
return ResponseEntity.ok().body(idResponse);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception ex) {
logger.error("runtimeException:", ex);
CodeResponse idResponse = new CodeResponse();
idResponse.setCode(ReturnCode.SYSTEM_IDENTIFY);
idResponse.setMessage(ex.getMessage() != null ? ex.getMessage() : "system error");
return ResponseEntity.ok().body(idResponse);
}
}
其中BusinessException 是自定义异常,如下:
package cn.test.account.exceptions;
public class BusinessException extends BaseException{
Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException() {
super();
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(String message) {
super(message);
}
public BusinessException(Throwable cause) {
super(cause);
}
public BusinessException(String message, Integer code,Throwable cause) {
super(message, cause);
this.code = code;
}
public BusinessException(String message, Integer code) {
super(message);
this.code = code;
}
}
package cn.test.account.exceptions;
public class BaseException extends RuntimeException {
public BaseException() {
super();
}
public BaseException(String message, Throwable cause) {
super(message, cause);
}
public BaseException(String message) {
super(message);
}
public BaseException(Throwable cause) {
super(cause);
}
}
疑惑点:那么当有一个异常被捕获(即try-catch)后,会走全局异常还是catch中的逻辑呢?
try catch和全局异常的执行顺序:
- 当发生异常时,首先会检查当前方法中是否存在 try-catch 块来捕获该异常。如果存在适用的 catch 块,则会执行 catch 块中的代码,并且程序将继续执行 catch 块之后的代码。此时,全局异常处理器不会被触发。
- 如果当前方法中没有适用的 try-catch 块来捕获异常,或者异常在 try-catch 块中没有被捕获,则异常将被传递给调用该方法的上层调用栈。
- 如果异常一直传递到了最外层的调用栈,并且没有被任何 try-catch 块捕获,那么全局异常处理器将会被触发。