优雅的异常处理机制
1、 在web系统开发过程中,前后端分离架构模式下,后台的逻辑判断和异常处理(例如非空验证,长度验证等等)直接抛给前端总是一个比较痛苦的事情,可能需要前端对后端返回的某一个值进行判断,再进行异常的输出。 这种模式下,如果判断信息太多,接口的出参DTO数据结构还需要不断地重新构建,拓展性十分差劲。
2、如果能够以全局的形式处理,后端有逻辑判断只抛异常,前端对于httpStatus进行判断(500时自动走异常分支),这样一来,前端不需要做频繁的参数校验,后端也不需要对接口结构进行不断调整,这样的架构,是每个程序员乐于接受的。
3、先上图看效果
前端接收是只需要在异常catch或者判断HttpStatus的范围即可进行异常拦截,减少了大量的代码
定义优雅的全局自定义系统异常类
BlogSystemException.java 定义自定义的异常类
最好是继承自RuntimeException ,不然会在编译期,需要你手动在方法上抛出
/**
* @Describe: 主动抛出的异常,用于控制器处理
* @Author: zjhChester
* @Date: 14:47 2020/9/29
*/
public class BlogSystemException extends RuntimeException {
public BlogSystemException() {
super();
}
public BlogSystemException(String message) {
super("系统出现异常:"+message);
}
public BlogSystemException(String message, Throwable cause) {
super(message, cause);
}
public BlogSystemException(Throwable cause) {
super(cause);
}
protected BlogSystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
SystemExceptionHandler.java 异常处理器
通过ResponseEntity
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.zjhwork.conf.exception.BlogSystemException;
import xyz.zjhwork.resmodel.ResponseModel;
import java.util.Objects;
/**
* @Describe: 处理系统自定义总线异常的处理
* @Author: zjhChester
* @Date: 14:54 2020/9/29
*/
@Slf4j
@Component
@ControllerAdvice
public class SystemExceptionHandler {
@ResponseBody
@ExceptionHandler({BlogSystemException.class})
//此处的入参只需要写自定义异常类的父类即
public ResponseEntity<ResponseModel> handleValidException(RuntimeException e) {
//日志记录错误信息
log.error(Objects.requireNonNull(e.getMessage()));
//将错误信息返回给前台
return ResponseEntity.status(500).body( ResponseModel.failResModel(99999999,Objects.requireNonNull(e.getMessage()), e.getStackTrace()));
}
}
测试
@GetMapping("/{id}")
public ResponseModel get(@PathVariable("id") Integer id){
throw new BlogSystemException("测试主动抛出异常2");
}