全局异常处理器
Spring的异常处理器,只需要在类上加上@RestControllerAdvice是一个组合注解,是由@ControllerAdvice和@ResponseBody的组合。第一个注解用于定义@ExceptionHandler、@InitBinder和@ModelAttribute方法,这些方法对所有@RequestMapping方法都有效,第二个注解用于指示方法的返回值应该直接写入HTTP响应体,通常用于创建RESTful Web服务。
接下来是例子(学习的开源项目):
@RestControllerAdvice public class GlobalExceptionHandler { /** * 拦截参数验证异常 */ @SneakyThrows @ExceptionHandler(value = MethodArgumentNotValidException.class) public Result validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) { BindingResult bindingResult = ex.getBindingResult(); FieldError firstFieldError = CollectionUtil.getFirst(bindingResult.getFieldErrors()); String exceptionStr = Optional.ofNullable(firstFieldError) .map(FieldError::getDefaultMessage) .orElse(StrUtil.EMPTY); log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionStr); return Results.failure(BaseErrorCode.CLIENT_ERROR.code(), exceptionStr); } }
在学习时,每个方法关注的是入参,返回值和返回值类型。MethodArgumentNotValidException是Spring Web自带的参数验证的类,返回的Results是自定义的结果返回类型。
此外处理逻辑还有个FieldError,它
是 Spring 框架中的一个类,用于表示数据验证过程中出现的字段错误。
Optional类是java8引入的新容器,它可以保存一个值,也可以不保存任何值(即为空)。ofNullable方法是java8的新特性,它用于创建一个可能为空的Optional
对象。具体过程,它接受一个可能为空的值作为参数,然后根据参数是否为空,返回一个Optional
对象。如果参数为空,则返回一个空的Optional
对象;如果参数不为空,则将参数包装成一个Optional
对象并返回。
Optional
的主要目的是为了避免NullPointerException
,并不能代替null值,对于确定不会为空的值,还是应该直接使用null
。
处理器总结:
在类上加上@RestControllerAdvice就能拦截异常,方法上在加上@ExceptionHandler负责异常处理的逻辑就能处理全局异常了。
@SneakyThrows注解
今天学习Spring全局异常处理器,发现一个lombok的@SneakyThrows注解,用于简化异常处理。通常用于简化方法中的异常处理,使得代码更加简洁和易于阅读。
@SneakyThrows
会自动将异常转换为RuntimeException
,从而避免手动编写try-catch
语句。
下面是一个使用@SneakyThrows
的示例:
readFile
方法使用了@SneakyThrows
注解,因此不需要在方法签名中添加throws IOException
。当readFile
方法抛出IOException
时,它会自动转换为RuntimeException
,从而避免手动编写try-catch
语句。
@SneakyThrows虽然简化了异常处理,但是在复杂场景中。由于覆盖了异常不能准确知道是RuntimeException的子类异常还是本身,出问题不方便定位,使用需要慎重。