全局异常处理除了是对业务处理运行情况的的统一反馈,也是业务处理发生异常的统一出口,可用来收集错误日志等相关操作。
方案说明:
- 基于Spring做全局异常处理、Slf4J做日志输出接口。
- 自定义异常通过code区别异常类型。
- 自定义异常通过printLog来决定是否打印日志,默认不打印,避免大量冗余日志信息。其他运行时异常都打印error级别日志。
- 实际业务代码开发,原则上不允许做try...catch处理,所有错误使用全局异常统一捕获。除非相关业务非常明确不需要抛出异常。
技术实现
自定义异常类
public class AppException extends RuntimeException {
// 错误码
private String code;
// 错误消息
private String msg;
// 是否打印日志(默认不打印)
private boolean printLog;
public AppException(String msg) {
this.msg = msg;
}
public AppException(String msg, boolean printLog) {
this.msg = msg;
this.printLog = printLog;
}
public AppException(String msg, String code) {
this.code = msg;
this.msg = code;
}
public AppException(String msg, String code, boolean printLog) {
this.code = msg;
this.msg = code;
this.printLog = printLog;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
基于spring做全局异常处理:
@RestControllerAdvice
@Slf4j
public class WebExceptionHandler {
/**
* 自定义异常
* @param e
* @param requestWrapper
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = AppException.class)
public Object exceptionHandler(AppException e, SecurityContextHolderAwareRequestWrapper requestWrapper) {
// 打印日志
if(e.isPrintLog()){
log.error(e.getMessage(), e);
}
// 返回错误消息
// ... return error msg
}
/**
* 受检查异常
* @param e
* @param requestWrapper
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = Exception.class)
public Object exceptionHandler(Exception e, SecurityContextHolderAwareRequestWrapper requestWrapper) {
// 打印日志
log.error(e.getMessage(), e);
// 返回错误消息
// ... return error msg
}
/**
* 运行时异常
* @param e
* @param requestWrapper
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = RuntimeException.class)
public Object exceptionHandler(RuntimeException e, SecurityContextHolderAwareRequestWrapper requestWrapper) {
// 打印日志
log.error(e.getMessage(), e);
// 返回错误消息
// ... return error msg
}
}