SpringBoot 全局异常处理+策略+反射异常
异常分类处理
GlobalBaseExceptionHandler(基础异常)
DataAccessException(持久层异常)
GlobalTokenAccessExceptionHandler (令牌授权异常)
GlobalInvocationTargetExceptionHandler(反射异常)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200320140613231.png)
GlobalBaseExceptionHandler(基础异常)
/**
* 基础异常抛出
* 包含 类型转换异常 数组下表越界 文件没有找到 输入输出 空指针 参数校验 自定义异常 除数为零
*
*
*/
@Slf4j
@RestControllerAdvice
public class GlobalBaseExceptionHandler {
/**
* 所有异常报错
* TODO 策略处理
* @param ex
* @return
* @throws Exception
*/
/**
* 类转换异常
* @param exception
* @return
*/
@ExceptionHandler(ClassCastException.class)
public Result classCastException(ClassCastException exception) {
return ResultFactory.of(DefaultResultCode.CLASS_CAST_EXCEPTION,exception.getMessage());
}
/**
* 数组下表越界异常
* @param exception
* @return
*/
@ExceptionHandler(ArrayIndexOutOfBoundsException.class)
public Result arrayIndexOutOfBoundsException(ArrayIndexOutOfBoundsException exception) {
return ResultFactory.of(DefaultResultCode.ARR_EXCEPTION,exception.getMessage());
}
/**
*
* @param exception
* @return
*/
@ExceptionHandler(FileNotFoundException.class)
public Result fileNotFoundException(FileNotFoundException exception) {
return ResultFactory.of(DefaultResultCode.FILE_NOT_FOUND_EXCEPTION,exception.getMessage());
}
/**
* 输入输出流异常
* @param exception
* @return
*/
@ExceptionHandler(IOException.class)
public Result iOException(IOException exception) {
return ResultFactory.of(DefaultResultCode.IO_EXCEPTION,exception.getMessage());
}
/**
* 空指针异常
* @param exception
* @return
*/
@ExceptionHandler(NullPointerException.class)
public Result nullPointerException(NullPointerException exception) {
exception.printStackTrace();
return ResultFactory.of(DefaultResultCode.NULL_EXCEPTION, exception.getMessage());
}
/**
* 除数为零
* @param exception
* @return
*/
@ExceptionHandler(ArithmeticException.class)
public Result arithmeticException(ArithmeticException exception) {
return ResultFactory.of(DefaultResultCode.DIVISOR_IS_ZERO_EXCEPTION, exception.getMessage());
}
/**
* 自定义异常
* @param exception
* @return
*/
@ExceptionHandler(CustomException.class)
public Result customException(CustomException exception) {
return ResultFactory.of(DefaultResultCode.DEFAULT_ERROR, exception.getMessage());
}
/**
* 对方法参数校验异常处理方法(仅对于表单提交有效,对于以json格式提交将会失效)
* 如果是表单类型的提交,则spring会采用表单数据的处理类进行处理(进行参数校验错误时会抛出BindException异常)
*/
@ExceptionHandler(BindException.class)
public Result handlerBindException(BindException exception) {
return handlerNotValidException(exception);
}
/**
* 对方法参数校验异常处理方法(前端提交的方式为json格式出现异常时会被该异常类处理)
* json格式提交时,spring会采用json数据的数据转换器进行处理(进行参数校验时错误是抛出MethodArgumentNotValidException异常)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handlerArgumentNotValidException(MethodArgumentNotValidException exception) {
return handlerNotValidException(exception);
}
private Result handlerNotValidException(Exception e) {
log.debug("begin resolve argument exception");
BindingResult result;
if (e instanceof BindException) {
BindException exception = (BindException) e;
result = exception.getBindingResult();
} else {
MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
result = exception.getBindingResult();
}
Map<String, Object> map = Maps.newHashMap();
if (result.hasErrors()) {
List<FieldError> fieldErrors = result.getFieldErrors();
fieldErrors.forEach(error -> {
map.put(error.getField(), error.getDefaultMessage());
});
}
return ResultFactory.of(DefaultResultCode.INVALID_PARAMETER, map.toString());
}
}
DataAccessException(持久层异常)
/**
*
* DataAccessException(持久层异常)
* sql异常 HttpMessageNotReadableException
*/
@RestControllerAdvice
public class GlobalDataAccessExceptionHandler {
/**
* sql异常
*
* @param exception
* @return
*/
@ExceptionHandler({BadSqlGrammarException.class, SQLException.class})
public Result sqlException(Exception exception) {
return ResultFactory.of(DefaultResultCode.SQL_EXCEPTION, exception.getMessage());
}
@ExceptionHandler({SQLIntegrityConstraintViolationException.class, ConstraintViolationException.class})
public Result sQLIntegrityConstraintViolationException(Exception exception) {
return ResultFactory.of(DefaultResultCode.SQL_INTEGRITY_CONSTRAINT_VIOLATION_EXCEPTION, exception.getMessage());
}
@ExceptionHandler({DuplicateKeyException.class})
public Result duplicateKeyException(DuplicateKeyException exception) {
return ResultFactory.of(DefaultResultCode.DUPLICATE_KEY_EXCEPTION, exception.getMessage());
}
/**
* HttpMessageNotReadableException
* @param exception
* @return
*/
@ExceptionHandler({HttpMessageNotReadableException.class})
public Result httpMessageNotReadableException(HttpMessageNotReadableException exception) {
return ResultFactory.of(DefaultResultCode.INVALID_FORMAT_EXCEPTION,exception.getMessage());
}
@ExceptionHandler({TransactionRequiredException.class})
public Result transactionRequiredException(TransactionRequiredException exception) {
return ResultFactory.of(DefaultResultCode.TRANSACTION_REQUIRED_EXCEPTION,exception.getMessage());
}
}
GlobalTokenAccessExceptionHandler (令牌授权异常)
/**
*
* GlobalTokenAccessExceptionHandler(令牌授权异常)
*/
@RestControllerAdvice
public class GlobalTokenAccessExceptionHandler {
/**
* 未授权
* @param exception
* @return
*/
@ExceptionHandler({UnauthorizedException.class})
public Result unauthorizedException(UnauthorizedException exception) {
return ResultFactory.of(DefaultResultCode.TOKEN_INVALID,exception.getMessage());
}
/**
* 权限错误
* @param exception
* @return
*/
@ExceptionHandler({ShiroException.class})
public Result shiroException(ShiroException exception) {
return ResultFactory.of(DefaultResultCode.TOKEN_INVALIDATION,exception.getMessage());
}
}
GlobalInvocationTargetExceptionHandler(反射异常 技术点)
/**
* 反射异常处理
*/
@RestControllerAdvice
public class GlobalInvocationTargetExceptionHandler {
private GlobalDataAccessExceptionHandler globalDataAccessExceptionHandler;
private GlobalBaseExceptionHandler globalBaseExceptionHandler;
private GlobalTokenAccessExceptionHandler globalTokenAccessExceptionHandler;
@Autowired
public GlobalInvocationTargetExceptionHandler(GlobalDataAccessExceptionHandler globalDataAccessExceptionHandler, GlobalBaseExceptionHandler globalBaseExceptionHandler, GlobalTokenAccessExceptionHandler globalTokenAccessExceptionHandler) {
this.globalDataAccessExceptionHandler = globalDataAccessExceptionHandler;
this.globalBaseExceptionHandler = globalBaseExceptionHandler;
this.globalTokenAccessExceptionHandler = globalTokenAccessExceptionHandler;
}
/**
* 反射调用异常
*
* @param exception
* @return
*/
@ExceptionHandler({InvocationTargetException.class})
public Result invocationTargetException(InvocationTargetException exception) throws IllegalAccessException, InvocationTargetException {
Throwable throwable = exception.getTargetException();
//判断当前异常
return (Result) chooseThrowableByType(throwable);
// // 判断异常case
// if (throwable.getCause() instanceof SQLIntegrityConstraintViolationException) {
// return globalDataAccessExceptionHandler.sQLIntegrityConstraintViolationException((Exception) throwable);
// } else {
// return ResultFactory.of(DefaultResultCode.REFLEX_EXCEPTION, exception.getMessage());
// }
}
public Object chooseThrowableByType(Throwable throwable) throws IllegalAccessException, InvocationTargetException {
Field[] fields = GlobalInvocationTargetExceptionHandler.class.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object fieldObj = field.get(this);
Method[] methods = field.getType().getDeclaredMethods();
for (Method method : methods) {
ExceptionHandler exceptionHandler=method.getAnnotation(ExceptionHandler.class);
if (ObjectUtils.isEmpty(exceptionHandler)) {
continue;
}
Class clzz = throwable.getClass();
for (Class<? extends Throwable> aClass : exceptionHandler.value()) {
if (clzz.isAssignableFrom(aClass)) {
method.setAccessible(true);
return (Result) method.invoke(fieldObj, throwable);
}
}
}
}
if (ObjectUtils.isEmpty(throwable.getCause())) {
return ResultFactory.of(DefaultResultCode.REFLEX_EXCEPTION, throwable.getMessage());
} else {
return chooseThrowableByType(throwable.getCause());
}
}
}
反射异常处理逻辑
1.首先GlobalInvocationTargetExceptionHandler 类中注入三大基础异常类对象 (使用spring bean注入的方式获取对象)
2.所有的异常类都继承自Throwable 通过throwable.getCause()可以获取反射异常是由那种异常造成的
3.递归