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

前言

     本文讲解使用 @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); } } }

猜你喜欢

转载自www.cnblogs.com/jtlgb/p/10661688.html