Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 317|回复: 0

springBoot 全局异常方式处理自定义异常 @RestControllerAdvice + @ExceptionHandler

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-2 06:19:56 | 显示全部楼层 |阅读模式

    前言

         本文讲解使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理,可以处理大部分开发中用到的自自定义业务异常处理了,再也不用在 Controller 层进行 try-catch 了
         代码示例地址(代码里面类名稍微有些不同): https://gitee.com/coderLOL/springboot-demos

    一、处理思路

    1. 思路:在sevice业务逻辑层 try{}catch(){} 捕获抛出,经由contorller 层抛到 自定义全局处理类 中处理自定义异常及系统异常。

         2、实现方式:使用 @RestControllerAdvice + @ExceptionHandler 注解方式实现全局异常处

    二、实现过程

     1、@ControllerAdvice 注解定义全局异常处理类 ,@ExceptionHandler 注解声明异常处        理方法。

         ( 本类方法中用到的 ResponseResultUtil 工具类, ResponseCodeEnum 枚举类,下面步骤中会介绍)

    import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @author 路飞 * @date 2018-8-21 * @description 全局异常处理: 使用 @RestControllerAdvice + @ExceptionHandler 注解方式实现全 * 局异常处理 */ @RestControllerAdvice public class GlobalExceptionHandler { private final Logger logger = LogManager.getLogger(GlobalExceptionHandler.class); /** * @author 路飞 * @date 2018-8-22 * @param e 异常 * @description 处理所有不可知的异常 */ @ExceptionHandler({Exception.class}) //申明捕获那个异常类 public ResponseResultVO globalExceptionHandler(Exception e) { this.logger.error(e.getMessage(), e); return new ResponseResultUtil().error(ResponseCodeEnum.OPERATE_FAIL); } /** * @author 路飞 * @date 2018-8-21 * @param e 异常 * @description 处理所有业务异常 */ @ExceptionHandler({BaseBusinessException.class}) public ResponseResultVO BusinessExceptionHandler(BaseBusinessException e) { this.logger.error(e); return new ResponseResultUtil().error(e.getCode(), e.getMessage()); } }

    2、定义一个用于返回页面结果信息的VO对象类:ResponseResultVO

    /** * @author 路飞 * @date 2018-8-21 * @description 请求响应对象 */ public final class ResponseResultVO<T> { /** * @description 响应码 */ private int code; /** * @description 响应消息 */ private String message; /** * @description 分页对象 (如果用不到,这个可以不写) */ private PageVO page; /** * @description 数据 */ private Object data; public final int getCode() { return this.code; } public final void setCode(int code) { this.code = code; } public final String getMessage() { return this.message; } public final void setMessage( String message) { this.message = message; } public final PageVO getPage() { return this.page; } public final void setPage( PageVO page) { this.page = page; } public final Object getData() { return this.data; } public final void setData(Object data) { this.data = data; } public ResponseResultVO(int code, String message, PageVO page, Object data) { super(); this.code = code; this.message = message; this.page = page; this.data = data; } }

    3、 定义一个对步骤2中 返回信息结果处理的工具类:ResponseResultUtil

    /** * @author zhangwenlong * @date 2018-8-20 * @description 请求响应工具类 */ public final class ResponseResultUtil { /** * @param code 响应码 * @param message 相应信息 * @param any 返回的数据 * @description 请求成功返回对象 */ public final ResponseResultVO success(int code, String message, PageVO page, Object any) { return new ResponseResultVO(code, message, page, any); } /** * @param any 返回的数据 * @description 请求成功返回对象 */ public final ResponseResultVO success(Object any) { int code = ResponseCodeEnum.SUCCESS.getCode(); String message = ResponseCodeEnum.SUCCESS.getMessage(); return this.success(code, message, null, any); } /** * @param any 返回的数据 * @description 请求成功返回对象 */ public final ResponseResultVO success(Object any, PageVO page) { int code = ResponseCodeEnum.SUCCESS.getCode(); String message = ResponseCodeEnum.SUCCESS.getMessage(); return this.success(code, message, page, any); } /** * @description 请求成功返回对象 */ public final ResponseResultVO success() { return this.success(null); } /** * @param responseCode 返回的响应码所对应的枚举类 * @description 请求失败返回对象 */ public final ResponseResultVO error(ResponseCodeEnum responseCode) { return new ResponseResultVO(responseCode.getCode(), responseCode.getMessage(), null, null); } /** * @param code 响应码 * @param message 相应信息 * @description 请求失败返回对象 */ public final ResponseResultVO error(int code, String message) { return new ResponseResultVO(code, message, null, null); } }

    4、为方便统一管理异常代码和信息之间的关系,建立枚举类: ResponseCodeEnum

    /** * @author 路飞 * @date 2018-8-20 * @description 响应码配置枚举 */ public enum ResponseCodeEnum { // 系统通用 SUCCESS(200, "操作成功"), UNLOGIN_ERROR(233, "没有登录"), OPERATE_FAIL(666, "操作失败"), // 用户 SAVE_USER_INFO_FAILED(2001, "保存用户信息失败"), GET_USER_INFO_FAILED(2002, "保存用户信息失败"), WECHAT_VALID_FAILED(2003, "微信验证失败"), GET_USER_AUTH_INFO_FAILED(2004, "根据条件获取用户授权信息失败"), SAVE_USER_AUTH_INFO_FAILED(2005, "保存用户授权失败"); private Integer code; private String message; ResponseCodeEnum(Integer code, String message) { this.code = code; this.message = message; } public final Integer getCode() { return this.code; } public final String getMessage() { return this.message; } }

    5、 

    (1)封装一个基础业务异常类(让所有自定义业务异常类 继承此 基础类):BaseBusinessException

    /** * @author zhangwenlong * @date 2018-8-21 * @description 价值分析系统所有的 业务异常父类 */ public class BaseBusinessException extends RuntimeException { private Integer code; // 给子类用的方法 public BaseBusinessException(ResponseCodeEnum responseCodeEnum) { this(responseCodeEnum.getMessage(), responseCodeEnum.getCode()); } private BaseBusinessException(String message, Integer code) { super(message); this.code = code; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } }

    (2)自定义的业务异常类 (例如):

                  自定义用户异常

    /** * @author 路费 * @date 2018-8-21 * @description 自定义用户异常 */ public class UserException extends BaseBusinessException { // 继承继承 业务异常类 public UserException(ResponseCodeEnum responseCodeEnum) { super(responseCodeEnum); } }

    6、service 层抛出

    /** * @author 路飞 * @date 2018-8-21 * @description 用户信息业务接口实现类 */ @Service("userInfoService") public class UserInfoSerimpl implements UserInfoService { private Logger logger = LoggerFactory.getLogger(UserInfoSerimpl.class); @Resource private UserInfoMapper userInfoMapper; // maybatis通用Mapper插件 /** * @author 路飞 * @date 2018-8-21 * @param userInfo 用户信息 * @description 保存用户信息 */ @Override public void saveUserInfo(UserInfo userInfo) { try { userInfoMapper.insertSelective(userInfo); } catch (Exception e) { logger.error("获取用户信息失败", e); //抛出自定义异常: ResponseCodeEnum.SAVE_USER_INFO_FAILED throw new UserException(ResponseCodeEnum.SAVE_USER_INFO_FAILED); } } }
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-2 15:42 , Processed in 0.065763 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表