当前位置: 首页 > news >正文

SpringBoot全局异常详解

一、前言

在日常的开发工作中,项目在运行过程中多多少少是避免不了报错的,对于报错信息肯定不可以把全部信息都抛给客户端去显示,这里就需要我们对常见的七种异常情况统一进行处理,让整个项目更加优雅。

二、全局异常介绍

这次博客的主角就是 @RestControllerAdvice 这个注解,这个一个组合注解由 @ControllerAdvice@ResponseBody 组成,@RestControllerAdvice 会帮助我们把信息转成json格式返回。

在全局异常处理类只需要在类上标注 @RestControllerAdvice ,并在处理相应异常的方法上使用 @ExceptionHandler 注解,写明处理哪个异常即可。

注:异常的拦截有顺序,子类异常会优先匹配子类异常处理器。

三、常用类封装

HttpStatus状态码常量类

这边定义了目前常见的响应的状态码


/*** 返回状态码**/
public class HttpStatus {/*** 操作成功*/public static final int SUCCESS = 200;/*** 对象创建成功*/public static final int CREATED = 201;/*** 请求已经被接受*/public static final int ACCEPTED = 202;/*** 操作已经执行成功,但是没有返回数据*/public static final int NO_CONTENT = 204;/*** 资源已被移除*/public static final int MOVED_PERM = 301;/*** 重定向*/public static final int SEE_OTHER = 303;/*** 资源没有被修改*/public static final int NOT_MODIFIED = 304;/*** 参数列表错误(缺少,格式不匹配)*/public static final int BAD_REQUEST = 400;/*** 未授权*/public static final int UNAUTHORIZED = 401;/*** 访问受限,授权过期*/public static final int FORBIDDEN = 403;/*** 资源,服务未找到*/public static final int NOT_FOUND = 404;/*** 不允许的http方法*/public static final int BAD_METHOD = 405;/*** 资源冲突,或者资源被锁*/public static final int CONFLICT = 409;/*** 不支持的数据,媒体类型*/public static final int UNSUPPORTED_TYPE = 415;/*** 系统内部错误*/public static final int ERROR = 500;/*** 接口未实现*/public static final int NOT_IMPLEMENTED = 501;/*** 系统警告消息*/public static final int WARN = 601;
}

AjaxResult统一封装返回的结果类

import java.util.HashMap;
import java.util.Objects;
/*** 操作消息提醒**/
public class AjaxResult extends HashMap<String, Object> {private static final long serialVersionUID = 1L;/*** 状态码*/public static final String CODE_TAG = "code";/*** 返回内容*/public static final String MSG_TAG = "msg";/*** 数据对象*/public static final String DATA_TAG = "data";/*** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。*/public AjaxResult() {}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg  返回内容*/public AjaxResult(int code, String msg) {super.put(CODE_TAG, code);super.put(MSG_TAG, msg);}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg  返回内容* @param data 数据对象*/public AjaxResult(int code, String msg, Object data) {super.put(CODE_TAG, code);super.put(MSG_TAG, msg);if (data != null) {super.put(DATA_TAG, data);}}/*** 返回成功消息** @return 成功消息*/public static AjaxResult success() {return AjaxResult.success("操作成功");}/*** 返回成功数据** @return 成功消息*/public static AjaxResult success(Object data) {return AjaxResult.success("操作成功", data);}/*** 返回成功消息** @param msg 返回内容* @return 成功消息*/public static AjaxResult success(String msg) {return AjaxResult.success(msg, null);}/*** 返回成功消息** @param msg  返回内容* @param data 数据对象* @return 成功消息*/public static AjaxResult success(String msg, Object data) {return new AjaxResult(HttpStatus.SUCCESS, msg, data);}/*** 返回警告消息** @param msg 返回内容* @return 警告消息*/public static AjaxResult warn(String msg) {return AjaxResult.warn(msg, null);}/*** 返回警告消息** @param msg  返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult warn(String msg, Object data) {return new AjaxResult(HttpStatus.WARN, msg, data);}/*** 返回错误消息** @return 错误消息*/public static AjaxResult error() {return AjaxResult.error("操作失败");}/*** 返回错误消息** @param msg 返回内容* @return 错误消息*/public static AjaxResult error(String msg) {return AjaxResult.error(msg, null);}/*** 返回错误消息** @param msg  返回内容* @param data 数据对象* @return 错误消息*/public static AjaxResult error(String msg, Object data) {return new AjaxResult(HttpStatus.ERROR, msg, data);}/*** 返回错误消息** @param code 状态码* @param msg  返回内容* @return 错误消息*/public static AjaxResult error(int code, String msg) {return new AjaxResult(code, msg, null);}/*** 是否为成功消息** @return 结果*/public boolean isSuccess() {return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));}/*** 是否为警告消息** @return 结果*/public boolean isWarn() {return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));}/*** 是否为错误消息** @return 结果*/public boolean isError() {return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));}/*** 方便链式调用** @param key* @param value* @return*/@Overridepublic AjaxResult put(String key, Object value) {super.put(key, value);return this;}
}

ServiceException业务异常类封装

/*** 业务异常类封装*/
public final class ServiceException extends RuntimeException
{private static final long serialVersionUID = 1L;/*** 错误码*/private Integer code;/*** 错误提示*/private String message;/*** 错误明细,内部调试错误*/private String detailMessage;/*** 空构造方法,避免反序列化问题*/public ServiceException(){}public ServiceException(String message){this.message = message;}public ServiceException(String message, Integer code){this.message = message;this.code = code;}public String getDetailMessage(){return detailMessage;}@Overridepublic String getMessage(){return message;}public Integer getCode(){return code;}public ServiceException setMessage(String message){this.message = message;return this;}public ServiceException setDetailMessage(String detailMessage){this.detailMessage = detailMessage;return this;}
}

InnerAuthException 内部认证异常


/*** 内部认证异常*/
public class InnerAuthException extends RuntimeException {private static final long serialVersionUID = 1L;public InnerAuthException(String message) {super(message);}
}

ServiceException 业务异常


/*** 业务异常**/
public final class ServiceException extends RuntimeException {private static final long serialVersionUID = 1L;/*** 错误码*/private Integer code;/*** 错误提示*/private String message;/*** 错误明细,内部调试错误* <p>* 和 {@link CommonResult#getDetailMessage()} 一致的设计*/private String detailMessage;/*** 空构造方法,避免反序列化问题*/public ServiceException() {}public ServiceException(String message) {this.message = message;}public ServiceException(String message, Integer code) {this.message = message;this.code = code;}public String getDetailMessage() {return detailMessage;}@Overridepublic String getMessage() {return message;}public Integer getCode() {return code;}public ServiceException setMessage(String message) {this.message = message;return this;}public ServiceException setDetailMessage(String detailMessage) {this.detailMessage = detailMessage;return this;}
}

NotPermissionException 未能通过的权限认证异常


import org.apache.commons.lang3.StringUtils;/*** 未能通过的权限认证异常**/
public class NotPermissionException extends RuntimeException {private static final long serialVersionUID = 1L;public NotPermissionException(String permission) {super(permission);}public NotPermissionException(String[] permissions) {super(StringUtils.join(permissions, ","));}
}

NotRoleException 未能通过的角色认证异常


import org.apache.commons.lang3.StringUtils;/*** 未能通过的角色认证异常**/
public class NotRoleException extends RuntimeException {private static final long serialVersionUID = 1L;public NotRoleException(String role) {super(role);}public NotRoleException(String[] roles) {super(StringUtils.join(roles, ","));}
}

GlobalExceptionHandler核心全局拦截配置类

/*** 全局异常处理器*/
@RestControllerAdvice
public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 权限码异常*/@ExceptionHandler(NotPermissionException.class)public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");}/*** 角色权限异常*/@ExceptionHandler(NotRoleException.class)public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");}/*** 请求方式不支持*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());return AjaxResult.error(e.getMessage());}/*** 业务异常*/@ExceptionHandler(ServiceException.class)public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {log.error(e.getMessage(), e);Integer code = e.getCode();return code !=null ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());}/*** 请求路径中缺少必需的路径变量*/@ExceptionHandler(MissingPathVariableException.class)public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));}/*** 拦截未知的运行时异常*/@ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生未知异常.", requestURI, e);return AjaxResult.error(e.getMessage());}/*** 系统异常*/@ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生系统异常.", requestURI, e);return AjaxResult.error(e.getMessage());}/*** 自定义验证异常*/@ExceptionHandler(BindException.class)public AjaxResult handleBindException(BindException e) {log.error(e.getMessage(), e);String message = e.getAllErrors().get(0).getDefaultMessage();return AjaxResult.error(message);}/*** 自定义验证异常*/@ExceptionHandler(MethodArgumentNotValidException.class)public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {log.error(e.getMessage(), e);String message = e.getBindingResult().getFieldError().getDefaultMessage();return AjaxResult.error(message);}/*** 内部认证异常*/@ExceptionHandler(InnerAuthException.class)public AjaxResult handleInnerAuthException(InnerAuthException e) {return AjaxResult.error(e.getMessage());}}
http://www.dtcms.com/a/264131.html

相关文章:

  • Electron 应用打包与分发:从开发到交付的完整指南
  • 多容器应用与编排——AI教你学Docker
  • Java-String类静态成员方法深度解析
  • AR 地产互动沙盘:为地产沙盘带来变革​
  • OpenCV-Python Tutorial : A Candy from Official Main Page(二)
  • 设备管理的重要性:企业数字化浪潮下的核心命题
  • 企业上网行为管理:零信任安全产品的对比分析
  • Linux基本命令篇 —— grep命令
  • 防 XSS和CSRF 过滤器(Filter)
  • go语言安装达梦数据完整教程
  • JVM 中的垃圾回收算法及垃圾回收器详解
  • 【仿muduo库实现并发服务器】Connection模块
  • CentOS 8中 更新或下载时报错:为仓库 ‘appstream‘ 下载元数据失败 : Cannot prepare internal
  • 02.SpringBoot常用Utils工具类详解
  • 从马赛克到色彩错乱:一次前景图像处理异常的全流程踩坑记录
  • Python实例题:基于 Python 的简单爬虫与数据可视化
  • 【IP 潮玩行业深度研究与学习】
  • 【仿muduo库实现并发服务器】eventloop模块
  • 香橙派3B学习笔记14:deb 打包程序_解包前后脚本运行
  • 折线图多数据处理
  • redux基本概念介绍 与 更新方式
  • 【网工|知识升华版|理论】ARQ机制|CSMA/CD协议
  • NetSuite 中如何在已关账期间内Unapply Customer Payment?
  • 数据结构day6——内核链表
  • 手机屏色斑缺陷修复及相关液晶线路激光修复原理
  • 一文讲清楚React合成事件机制和this的绑定问题
  • Pycharm命令行能运行,但绿色三角报错?
  • 51单片机制作万年历
  • java web2(黑马)
  • [Python] -基础篇7-新手常见Python语法错误及解决方案