SpringBoot自定义异常,优雅解决业务逻辑中的错误
文章目录
- 前言
- 设计
- 1. 自定义枚举类
- 2. 自定义异常
- 3. 异常全局处理
- 4. 使用
前言
在我们开发中,总会碰到一些异常 ---------- 运行时异常(不受检异常):RuntimeException类极其子类表示JVM在运行期间可能出现的错误。编译器不会检查此类异常,并且不要求处理异常,比如用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。
对于这些异常,如果返回给前端,会给用户代码很不好的体验,因为用户不知道 NullPointerException 等异常的意思,只会吐槽我们的项目,严重会导致用户流失,下面我们优雅的解决程序运行中的一场
设计
1. 自定义枚举类
public enum ResultEnum {UNKNOWN_ERROR(-100, "未知错误"),NEED_LOGIN(-1, "未登录"),REPEAT_REGISTER(-2, "该用户已注册"),USER_NOT_EXIST(-3, "不存在该用户"),PASSWORD_ERROR(-4, "密码错误"),EMPTY_USERNAME(-5, "用户名为空"),EMPTY_PASSWORD(-6, "密码为空"),SUCCESS(0, "success"),SYSTEM_ERROR(500,"手速太快了,慢点");private Integer code;private String msg;private ResultEnum(Integer code, String msg) {this.code = code;this.msg = msg;}public Integer getCode() {return code;}public String getMsg() {return msg;} }
2. 自定义异常
package com.yxl.exception;import com.yxl.enums.ResultEnum;/*** @Author:byteblogs* @Date:2018/09/27 12:52*/
public class BusinessException extends RuntimeException {private int code;private String errMsg;public BusinessException(ResultEnum resultEnum){this.code = resultEnum.getCode();this.errMsg = resultEnum.getMsg();}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getErrMsg() {return errMsg;}public void setErrMsg(String errMsg) {this.errMsg = errMsg;}
}
3. 异常全局处理
创建handler文件夹
新增ExcepetionHandler类
加入 @ControllerAdvice 注解
- 对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不仅限于此。ControllerAdvice拆分开来就是Controller
Advice,关于Advice,前面我们讲解Spring
Aop时讲到,其是用于封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ContrllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行“切面”环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:
结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的;
处理全局异常
- ResultBody 是返回的项目统一格式
package com.yxl.handler;import com.yxl.enums.ResultEnum;
import com.yxl.exception.BusinessException;
import com.yxl.po.ResponseMessage;
import com.yxl.po.ResultBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import java.util.stream.Collectors;@ControllerAdvice
public class ExceptionHandler {private final static Logger logger= LoggerFactory.getLogger(ExceptionHandler.class);/*** 处理其他异常* @param e* @return*/@org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class)@ResponseBodypublic ResponseMessage handel(Exception e){if(e instanceof BusinessException){BusinessException myException =(BusinessException)e;return ResultBody.error( myException.getCode(),myException.getMessage());}else {logger.error("[系统异常] {}",e);return ResultBody.error(ResultEnum.SYSTEM_ERROR);}}/*** 处理BusinessException异常* @param e* @return*/@org.springframework.web.bind.annotation.ExceptionHandler(value = BusinessException.class)@ResponseBodypublic ResponseMessage busin(BusinessException e) {return ResultBody.error(e.getCode(), e.getErrMsg());}/*** 处理空指针的异常** @param req* @param e* @return*/@org.springframework.web.bind.annotation.ExceptionHandler(value = NullPointerException.class)@ResponseBodypublic ResponseMessage exceptionHandler(HttpServletRequest req, NullPointerException e) {logger.error("发生空指针异常!原因是:", e);return ResultBody.error(ResultEnum.SYSTEM_ERROR);}/*** 处理参数校验异常** @param req* @param e* @return*/@org.springframework.web.bind.annotation.ExceptionHandler(value = MethodArgumentNotValidException.class)@ResponseBodypublic ResponseMessage exceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e) {logger.error("参数校验异常:", e);String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());return ResultBody.error(ResultEnum.SYSTEM_ERROR);}/*** 处理参数校验异常 --Json 转换异常* @param req* @param e* @return*/@org.springframework.web.bind.annotation.ExceptionHandler(value = HttpMessageNotReadableException.class)@ResponseBodypublic ResponseMessage exceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {logger.error("参数校验异常-json转换异常:", e);return ResultBody.error(ResultEnum.SYSTEM_ERROR);}}
4. 使用
@GetMapping("/test2")public ResponseMessage test2(@ApiParam(value = "id")@RequestParam(required = false) Long id) {//如果等于空抛出异常if(Objects.isNull(id)){throw new BusinessException(ResultEnum.EMPTY_USERNAME);}return ResultBody.success();}
- 结果 抛出了我们自定义的枚举异常
SpringBoot自定义异常,优雅解决业务逻辑中的错误相关推荐
- SpringBoot框架实现简单业务逻辑
SpringBoot框架实现简单业务逻辑 总述 Entity层 Dao层 Mapper.xml Service层 ServiceImpl Controller层 完整的业务逻辑实现写法示例 Dao层声 ...
- (转)淘淘商城系列——在业务逻辑中添加缓存
http://blog.csdn.net/yerenyuan_pku/article/details/72871268 上文我们一起学习了如何使用Spring容器来管理Redis单机版和集群版实现,本 ...
- 如何优雅的处理业务逻辑中的定时和延时问题?
本文将从如何处理业务流程和信息分发中的定时和延时问题出发,横向比较了业界常见的几种方案,如直接多线程编码.Spring定时调度框.大型分布式调度框架.消息中间件定时消息,因为消息中间件接口友好,调用方 ...
- 五星元老大飞哥,教半年Java实习生小飞飞:优雅解决历史代码中的新需求
事件起因 6月中旬,可爱的产品大飞哥穿着鸿星尔克,帅气极了,过来给我提了一个临时需求,需要我对商品创建/更新业务中由开放平台对接而来的请求做一个Check,如果符合要求,则再做一段稍微复杂的逻辑处理. ...
- 快速而优雅的处理 JavaScript 中的错误与异常(一键 get 新技能)
古之立大事者,不惟有超世之才,亦必有坚忍不拔之志.--苏轼 写在前面 在我们的实际编程中,抛出异常(代码报错)是最正常不过的,但是怎么处理异常这就要因人而异的,有的人遇到异常,通常会通过某种办法解决这 ...
- 基于Redis解决业务场景中延迟队列的应用实践
文章目录 一.业务概述 二.代码实现 2.1.工单队列实现 2.1.1.定义上下文类(`WorkOrderContext`) 2.1.2.定义抽象缓存类(`AbstractCacheManager`) ...
- 业务逻辑中的测试总结(二)----业务与数据库交互需求的测试分解
对服务器端的测试,免不了对服务器端的接口与数据库之间进行各种交互的业务测试.这类隐藏类需求的分解实际上也能使测试人员站在一个更高的角度去分解实际的业务需求.对数据库的操作,一般都是增删查改这四类,所以 ...
- 队列管理器连接数设置_详解!基于Redis解决业务场景中延迟队列的应用实践,你不得不服啊...
一.业务概述 我们假定设置两个队列,一个队列维护正式工单,另一个队列维护挂起工单.对于挂起操作,我们通过Redis设置key有效时间,当key失效时,客户端监听失效事件,获取工单,实现 挂起工单队列的 ...
- 学习淘淘商城第三十四课(在业务逻辑中添加缓存)
上节课我们一起学习了如何用Spring容器来管理Redis单机版和集群版实现.这节我们来学习下在业务中添加缓存. Redis添加缓存有两种方式,一种是set,另一种是hset,这两种方式的不同之处是h ...
最新文章
- [PWA] Show Notifications when a Service Worker is Installed or Updated
- 华为手机服务器响应,服务器响应优化
- 使用Postman测试https接口时的小问题记录
- [译]ASP.NET 5 Configuration
- 【vn.py学习笔记(七)】vn.py rqdata封装、datasbase等数据服务源码阅读
- Vue3使用Echarts图表
- PR(Adobe Premiere Pro)软件基础知识
- 手机微信群控系统和云控详细说明
- 延时降低90% | 国内首份《超低延时直播(快直播)白皮书》技术解码
- 用 vs 跑 lvgl 模拟器
- about ContentProvider
- Unity——用代码实现序列帧动画
- IronMCC 多媒体展厅中控系统
- 搜狗CEO王小川自述:如何用“三级火箭”杀出重围!
- pc全屏网页布局小技巧
- iOS马甲包过审技巧汇总
- pstats for Windows
- 寄存器堆计算机组成实验,《计算机组成原理》实验报告——寄存器堆
- java 1l_java - 为什么生成长serialVersionUID而不是简单的1L?
- Famous Quotes by Dee Cohen LCSW
热门文章
- Nginx 1.9 安装 ngx_pagespeed 模块
- 一种基于Harris-Laplace算法的角点检测方法(Matlab代码实现)
- 听见丨HTC发布新款Vive Pro,采用高分辨率OLED屏并内置耳机 高通在CES上发布新芯片,可将蓝牙耳机续航延长3倍
- Oss endpoint can‘t be empty.
- 浅谈一个完整网站配色方案设计大法3实战篇
- 新闻文本分类--任务5 基于深度学习的文本分类2
- 离群索居者,不是野兽便是神灵!
- 成功解决代码运行的时候出现的warnings警告问题
- 阅读nutch.Analysis.jj
- 关于微信分享接口,手机分享时候描述变链接的解决方法以及图片logo不显示问题解决方法