springboot中使用@RestControllerAdvice注解,完成优雅的全局异常处理类 您所在的位置:网站首页 springboot多个controller springboot中使用@RestControllerAdvice注解,完成优雅的全局异常处理类

springboot中使用@RestControllerAdvice注解,完成优雅的全局异常处理类

2024-07-14 19:33| 来源: 网络整理| 查看: 265

需求

springboot中使用@RestControllerAdvice注解,完成优雅的全局异常处理类,可以针对所有异常类型先进行通用处理后再对特定异常类型进行不同的处理操作。

注解讲解 @RestControllerAdvice注解

@RestControllerAdvice是一个用于定义全局异常处理器的注解。当应用程序内发生未捕获的异常时,全局异常处理器将捕获该异常并返回对应的响应,以避免应用程序崩溃。它可以处理所有控制器中抛出的异常,包括请求处理方法中的异常、控制器构造函数中的异常等。

@RestControllerAdvice注解是@ControllerAdvice和@ResponseBody注解的组合,它的作用是将所有的异常处理结果都以JSON格式返回给客户端。

具体来说,当控制器中发生异常时,SpringBoot会在全局异常处理器中查找与异常匹配的处理方法,并执行该方法来处理异常。

处理方法可以返回任何类型的值,如果返回对象是DataVO类型,则会将其转换为JSON格式并返回给客户端。

如果返回值是String类型,则会将其解释为视图名称,并使用视图解析器来解析视图并生成HTML响应。

因此,使用@RestControllerAdvice注解可以方便地定义全局异常处理器,并将所有异常处理结果以JSON格式返回给客户端。

@ExceptionHandler注解

@ExceptionHandler是一个注解,用于定义异常处理方法。

当控制器中发生异常时,Spring Boot会在@ControllerAdvice或@RestControllerAdvice注解的类中查找与异常匹配的@ExceptionHandler注解标记的方法,并执行该方法来处理异常。

@ExceptionHandler注解可以定义一个或多个异常类型,并将它们映射到对应的异常处理方法。当控制器中发生指定类型的异常时,SpringBoot会自动调用对应的异常处理方法,并将异常对象传递给该方法作为参数。

一般的全局异常处理类 @Slf4j @RestControllerAdvice public class GlobalExceptionHandler { private static final String DEFAULT_ERROR_MESSAGE = "系统繁忙,请稍后再试"; @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class}) public DataVO handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) { log.error(e.getMessage(), e); return new DataVO(SysConstant.CODE_ERROR, "当前主键存在于其他表的外键约束,请先处理父表中的该外键"); } @ExceptionHandler(value = {FileNotFoundException.class}) public DataVO handleFileNotFoundException(FileNotFoundException e) { log.error(e.getMessage(), e); return new DataVO(SysConstant.CODE_ERROR, "路径不存在"); } @ExceptionHandler(value = {Exception.class}) public DataVO handleException(Exception e) { log.error(e.getMessage(), e); return new DataVO(SysConstant.CODE_ERROR, DEFAULT_ERROR_MESSAGE); } }

如例所示,使用@RestControllerAdvice注解声明了GlobalExceptionHandler作为全局异常处理类,在这个类中的方法使用@ExceptionHandler注解指定某个方法处理对应的错误类型。

在这个一般的全局处理类中,@ExceptionHandler注解会根据异常类型选择最精确的处理方法进行处理,如果没有找到对应的处理方法,则会选择更加通用的处理方法。这样的处理方式会导致代码重复,每个处理方法都需要写一遍通用的操作,例如日志记录。

改进全局异常处理类

为了解决这个问题,我们可以将通用的异常处理逻辑抽象到一个方法中,并在处理方法中调用该方法

@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { private static final String DEFAULT_ERROR_MESSAGE = "系统繁忙,请稍后再试"; @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class}) public DataVO handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) { log.error(e.getMessage(), e); return handleException(DEFAULT_ERROR_MESSAGE, e); } @ExceptionHandler(value = {FileNotFoundException.class}) public DataVO handleFileNotFoundException(FileNotFoundException e) { log.error(e.getMessage(), e); return handleException(DEFAULT_ERROR_MESSAGE, e); } @ExceptionHandler(value = {Exception.class}) public DataVO handleException(Exception e) { log.error(e.getMessage(), e); return handleException(DEFAULT_ERROR_MESSAGE, e); } private DataVO handleException(String defaultMessage, Throwable e) { if (e instanceof BusinessException) { return new DataVO(SysConstant.CODE_ERROR, e.getMessage()); } else if (e instanceof MethodArgumentNotValidException) { return new DataVO(SysConstant.CODE_ERROR, ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage()); } else { return new DataVO(SysConstant.CODE_ERROR, defaultMessage); } } }

在这个示例中,定义了一个私有方法handleException,该方法接受一个默认错误消息和一个Throwable对象作为参数,并返回一个DataVO对象。

在处理方法中,调用handleException方法来处理异常,并将默认错误消息作为参数传递给handleException方法。

这样,我们就可以将通用的异常处理逻辑抽象到一个方法中,避免了重复代码。同时,我们也可以在handleException方法中添加自己的逻辑,例如记录日志等。

优雅的全局异常处理类

handleException方法中的if-else语句太过臃肿,可以使用Map来优化这个方法

@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { private static final String errorMsg = SysConstant.DEFAULT_ERROR; private static final Map


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有