0


Spring Boot中的全局异常处理:@RestControllerAdvice的应用

在现代Web开发中,异常处理是一个不可或缺的部分。良好的异常处理不仅能提高系统的健壮性,还能提升用户体验。在Spring Boot中,全局异常处理的实现可以通过使用

@RestControllerAdvice

注解来完成。本文将详细介绍如何使用

@RestControllerAdvice

@ExceptionHandler

来统一处理异常,并给出具体的实现示例。

1.

@RestControllerAdvice

概述

@RestControllerAdvice

是Spring MVC提供的一个功能强大的注解,用于全局处理控制器中的异常。它相当于

@ControllerAdvice

@ResponseBody

的组合,可以用于定义以下三种功能:

  1. **@ExceptionHandler**:处理特定的异常,并将响应返回给前端。
  2. **@InitBinder**:预处理Web请求数据的绑定。
  3. **@ModelAttribute**:将数据绑定到模型中,以便在控制器的@RequestMapping方法中使用。
@RestControllerAdvice

自动被Spring的组件扫描机制检测到,若应用通过MVC命令空间或MVC Java编程方式配置,该功能默认自动开启。

2. 实现全局异常处理

在实现全局异常处理时,我们通常会定义一个异常处理类,这个类中包含多个异常处理方法,每个方法对应一种或多种异常类型。下面是一个典型的实现示例。

2.1 全局异常处理器

importcom.sugon.cloud.lowcode.result.ReturnResult;importlombok.extern.slf4j.Slf4j;importorg.mybatis.spring.MyBatisSystemException;importorg.springframework.web.HttpRequestMethodNotSupportedException;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.RestControllerAdvice;importjavax.naming.AuthenticationException;importjavax.servlet.http.HttpServletRequest;importstaticcom.sugon.cloud.lowcode.constants.SplitCharacter.LEFT_PARENTHESES;importstaticcom.sugon.cloud.lowcode.constants.SplitCharacter.RIGHT_PARENTHESES;importstaticcom.sugon.cloud.lowcode.result.CodeMessageEnum.*;@RestControllerAdvice@Slf4jpublicclassGlobalExceptionHandler{@ExceptionHandler(value =BizException.class)@ResponseBodypublicReturnResultbizExceptionHandler(HttpServletRequest req,BizException e){
    log.error("发生业务异常: {}, 请求接口: {}", e.getMessage(), req.getRequestURI());returnReturnResult.error(e.getCode(), e.getMessage());}@ExceptionHandler(value =NullPointerException.class)@ResponseBodypublicReturnResultexceptionHandler(HttpServletRequest req,NullPointerException e){
    log.error("空指针异常信息: {}, 请求接口: {}", e, req.getRequestURI());returnReturnResult.error(NULL_POINT_ERROR_EXCEPTION.getCode(),NULL_POINT_ERROR_EXCEPTION.getMessage()+RIGHT_PARENTHESES+ e.getMessage()+LEFT_PARENTHESES);}@ExceptionHandler(value =HttpRequestMethodNotSupportedException.class)@ResponseBodypublicReturnResultmethodNotSupportedExceptionHandler(HttpServletRequest req,Exception e){
    log.error("请求方法异常信息: {},请求接口: {}", e, req.getRequestURI());returnReturnResult.error(REQUEST_METHOD_ERROR.getCode(),REQUEST_METHOD_ERROR.getMessage()+RIGHT_PARENTHESES+ e.getMessage()+LEFT_PARENTHESES);}@ExceptionHandler(value =MyBatisSystemException.class)@ResponseBodypublicReturnResultsqlSyntaxErrorExceptionHandler(HttpServletRequest req,Exception e){
    log.error("MyBatis系统异常信息: {},请求接口: {}", e, req.getRequestURI());returnReturnResult.error(INNER_FRAME_EXCEPTION.getCode(),INNER_FRAME_EXCEPTION.getMessage()+RIGHT_PARENTHESES+ e.getMessage()+LEFT_PARENTHESES);}@ExceptionHandler(value =AuthenticationException.class)publicReturnResultincorrectCredentialsException(HttpServletRequest request,AuthenticationException e){
    log.error("用户名或密码不正确: {}, 请求接口: {}", e, request.getRequestURI());returnReturnResult.error(USER_CREDENTIALS_ERROR);}@ExceptionHandler(value =UserException.class)publicReturnResultincorrectUserException(HttpServletRequest request,UserException e){
    log.error("用户信息异常: {}, 请求接口: {}", e, request.getRequestURI());returnReturnResult.error(e.getCode(), e.getMessage());}@ExceptionHandler(value =Exception.class)@ResponseBodypublicReturnResultexceptionHandler(HttpServletRequest req,Exception e){
    e.printStackTrace();
    log.error("未知异常: {}, 请求接口: {}", e, req.getRequestURI());returnReturnResult.error(INTERNAL_SERVER_ERROR.getCode(),INTERNAL_SERVER_ERROR.getMessage()+RIGHT_PARENTHESES+ e.getMessage()+LEFT_PARENTHESES);}}

2.2 自定义业务异常类

importcom.sugon.cloud.lowcode.result.BaseResultInterface;importcom.sugon.cloud.lowcode.result.CodeMessageEnum;importio.swagger.annotations.ApiModel;importio.swagger.annotations.ApiModelProperty;@ApiModel(description="业务异常数据")publicclassBizExceptionextendsRuntimeExceptionimplementsBaseResultInterface{privatestaticfinallong serialVersionUID =1L;@ApiModelProperty(value ="错误码")privateString code;@ApiModelProperty(value ="错误信息")privateString message;publicBizException(){super();}publicBizException(CodeMessageEnum codeMessageEnum){super(codeMessageEnum.getCode());this.code = codeMessageEnum.getCode();this.message = codeMessageEnum.getMessage();}publicBizException(CodeMessageEnum codeMessageEnum,Throwable cause){super(codeMessageEnum.getCode(), cause);this.code = codeMessageEnum.getCode();this.message = codeMessageEnum.getMessage();}publicBizException(CodeMessageEnum codeMessageEnum,String message,Throwable cause){super(codeMessageEnum.getCode(), cause);this.code = codeMessageEnum.getCode();this.message = message;}publicBizException(String message){super(message);this.message = message;}publicBizException(String code,String message){super(code);this.code = code;this.message = message;}publicBizException(String code,String message,Throwable cause){super(code, cause);this.code = code;this.message = message;}@OverridepublicThrowablefillInStackTrace(){returnthis;}@OverridepublicStringgetCode(){returnthis.code;}@OverridepublicStringgetMessage(){returnthis.message;}}

3. 统一返回格式

在上述代码中,所有的异常处理方法返回的是

ReturnResult

对象,它封装了返回给前端的数据。

ReturnResult

类的设计使得前端可以统一解析和展示错误信息。

3.1 返回结果类

importcom.alibaba.fastjson.JSONObject;importio.swagger.annotations.ApiModel;importio.swagger.annotations.ApiModelProperty;importlombok.Getter;importlombok.Setter;importstaticcom.sugon.cloud.lowcode.result.CodeMessageEnum.*;@Setter@Getter@ApiModel(description="返回响应数据")publicclassReturnResult<T>{@ApiModelProperty(value ="状态码")privateString code;@ApiModelProperty(value ="响应信息")privateString message;@ApiModelProperty(value ="响应对象")privateT result;@ApiModelProperty(value ="是否成功")privateboolean success =true;publicReturnResult(){}publicReturnResult(CodeMessageEnum codeMessageEnum){this.code = codeMessageEnum.getCode();this.message = codeMessageEnum.getMessage();}publicstaticReturnResultsuccess(){returnsuccess(null);}publicstatic<T>ReturnResult<T>success(T data){returnsuccess(SUCCESS, data);}publicstatic<T>ReturnResult<T>loginSuccess(T data){returnsuccess(SUCCESS_LOGIN, data);}publicstaticReturnResultloginOutSuccess(){returnsuccess(SUCCESS_LOGOUT,null);}privatestatic<T>ReturnResult<T>success(CodeMessageEnum codeMessageEnum,T data){ReturnResult<T> result =newReturnResult<>();
    result.setCode(codeMessageEnum.getCode());
    result.setMessage(codeMessageEnum.getMessage());
    result.setResult(data);return result;}publicstaticReturnResulterror(CodeMessageEnum codeMessageEnum){returnerror(codeMessageEnum.getCode(), codeMessageEnum.getMessage());}publicstaticReturnResulterror(CodeMessageEnum codeMessageEnum,String message){returnerror(codeMessageEnum.getCode(), message);}publicstaticReturnResulterror(String code,String message){ReturnResult result =newReturnResult();
    result.setCode(code);
    result.setMessage(message);
    result.setSuccess(false);return result;}@OverridepublicStringtoString(){returnJSONObject.toJSONString(this);}}

4. 总结

通过

@RestControllerAdvice

@ExceptionHandler

,我们可以在Spring Boot应用中实现全局异常处理,统一管理和处理所有异常。这样不仅可以

减少重复代码,还能使代码更加整洁,提高可维护性。同时,通过统一的返回格式,前端处理响应数据时也能更加方便。

希望这篇文章对您在Spring Boot中实现全局异常处理有所帮助。如有任何问题或建议,欢迎交流探讨。

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/run65536/article/details/140851161
版权归原作者 琴剑飘零西复东 所有, 如有侵权,请联系我们删除。

“Spring Boot中的全局异常处理:@RestControllerAdvice的应用”的评论:

还没有评论