前言

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

springBoot 全局异常方式处理自定义异常 @RestControllerAdvice + @ExceptionHandler的更多相关文章

  1. SpringBoot全局异常拦截

    SpringBoot全局异常捕获 使用到的技能 @RestControllerAdvice或(@ControllerAdvice+@ResponseBody) @ExceptionHandler 代码 ...

  2. SpringBoot项目中的全局异常处理器 Failed to invoke @ExceptionHandler method

    文件下载代码 @RequestMapping(value = { "/data/docking/picture/{id}/{empi}" }) public JsonApi pic ...

  3. springboot 全局异常捕获,异常流处理业务逻辑

    前言 上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的.参数异常springboot默认的返回结构: { "timestamp": ...

  4. SpringBoot 全局异常配置

    在日常web开发中发生了异常,往往是需要通过一个统一的异常处理来保证客户端能够收到友好的提示. 一.默认异常机制 默认异常处理(SpringBoot 默认提供了两种机制,一种是针对于web浏览器访问的 ...

  5. SpringBoot处理异常方式

    SpringBoot提供了多种处理异常方式,以下为常用的几种 1. 自定义错误异常页面 SpringBoot默认的处理异常的机制:SpringBoot默认的已经提供了一套处理异常的机制.一旦程序中出现 ...

  6. 自定义Springboot全局异常类

    一.简要说明 如何实现网上文章基本是随便一搜就可以很快找到, 这里不再赘述. 二.Spring-web和Spring-webmvc 通过idea查看到两个注解位于 spring-web-5.2.2.R ...

  7. SpringBoot 全局异常拦截捕获处理

    一.全局异常处理 //Result定义全局数据返回对象 package com.xiaobing.demo001.domain; public class Result { private Integ ...

  8. Spring boot异常统一处理方法:@ControllerAdvice注解的使用、全局异常捕获、自定义异常捕获

    一.全局异常 1.首先创建异常处理包和类 2.使用@ControllerAdvice注解,全局捕获异常类,只要作用在@RequestMapping上,所有的异常都会被捕获 package com.ex ...

  9. springboot全局异常拦截源码解读

    在springboot中我们可以通过注解@ControllerAdvice来声明一个异常拦截类,通过@ExceptionHandler获取拦截类抛出来的具体异常类,我们可以通过阅读源码并debug去解 ...

随机推荐

  1. ubuntu16.04 pycharm的安装

    Ubuntu 16.04安装PyCharm-Python IDE (转:http://www.linuxdiyf.com/linux/26442.html) 我最开始接触的编程语言是C/C++,之后由 ...

  2. docker的windows环境设置

    1.下载docker-install.exe安装VirtualBox.Git.Boot2Docker for Windows 2.设置环境变量,启动boot2docker Core Linux. 可以 ...

  3. 20175311胡济栋 2018-2019-2《Java程序设计》结对编程项目-四则运算 第二周 阶段性总结

    20175311胡济栋 2018-2019-2<Java程序设计>结对编程项目-四则运算 第二周 阶段性总结 需求分析 这是利用栈来设计一个计算器的第二阶段总结. 自动生成四则运算的题目( ...

  4. 权限模型AGDLP

    关于权限模型,认真学习下AD+FS应用在企业中,使用AGDLP模型,即可. AD是微软最牛逼的设计之一.

  5. 【原创】Mac book pro入手后,需要做哪些才能开始开展自动化测试工作

    2018国庆节,脑袋一热,入手了一台Mac book pro,从此掉坑到了这个异构的操作系统中,因为之前工作中接触了Windows.Linux.Unix等操作系统的诸多版本,基本的操作倒是不成问题,但 ...

  6. com.android.build.api.transformException报错的解决方法

    最近遇到一个问题:工程需要依赖模块1和模块2,但是模块1和模块2都使用了opencv,但opencv的版本不同,如果同时依赖两个模块,就会报错重复定义...如果模块2依赖模块1,工程再依赖模块2,也会 ...

  7. C语言排序算法学习笔记——选择类排序

    选择排序:每一趟(例如第i趟)在后面n-i+1(i=1,2,3,……,n-1)个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到n-1趟做完,待排序元素只剩下1个,就不用再选了. 简 ...

  8. 使用 Angular Console 提升开发体验

    Angular Console Angular Console 是一个用于扩展 Angular CLI 的强大工具,通过提供一个图形界面的形式,方便开发者使用 CLI 的功能. Angular CLI ...

  9. 2018-2019-2 20175328 《Java程序设计》第八周学习总结

    2018-2019-2 20175328 <Java程序设计>第八周学习总结 主要内容 泛型 泛型推出的主要目的是可以建立具有类型安全的集合框架,如链表.散列映射等数据结构. 1.泛型类声 ...

  10. thinkphp中上传图片以及制成缩略图

    form表单中必须有的一个属性: enctype=”multipart/form-data” html的写法: <form action="__SELF__" method= ...