自定义业务异常处理类加入全局处理器中

自定义业务异常处理类并将其加入全局异常处理器,从而避免业务层直接处理异常造成代码污染,达到业务清晰简洁。

 描述

在进行分类模块开发时,删除某个分类时当分类关联了菜品和套餐时,是不允许删除的。我们在管理端删除的时候会提示异常,我们使用自定义业务异常处理类并将其加入全局异常处理器,从而避免业务层直接处理异常造成代码污染,达到业务清晰简洁。

删除分类

删除分类需要注意的是当分类关联了菜品和套餐时,不允许删除。

1 基础删除,不检查关联的菜品

请求:

  • 如果忘了加注解@JsonFormat注解,会发生js获取主键时丢失精度,js只能读17位,而雪花算法Long类型是19位。

  • @JsonFormat(shape = JsonFormat.Shape.STRING)
    

代码:

    @DeleteMappingpublic R<String> page(Long ids){boolean success = categoryService.removeById(ids);if(success)return R.success("删除成功");else return R.error("删除失败");}
2 菜品和套餐的实体类,别忘了@JsonFormat

套餐:

/*** 套餐*/
@Data
public class Setmeal implements Serializable {private static final long serialVersionUID = 1L;@JsonFormat(shape = JsonFormat.Shape.STRING)private Long id;//分类id@JsonFormat(shape = JsonFormat.Shape.STRING)private Long categoryId;//套餐名称private String name;//套餐价格private BigDecimal price;//状态 0:停用 1:启用private Integer status;//编码private String code;//描述信息private String description;//图片private String image;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)@JsonFormat(shape = JsonFormat.Shape.STRING)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)@JsonFormat(shape = JsonFormat.Shape.STRING)private Long updateUser;}

菜品:

/**菜品*/
@Data
public class Dish implements Serializable {private static final long serialVersionUID = 1L;@JsonFormat(shape = JsonFormat.Shape.STRING)private Long id;//菜品名称private String name;//菜品分类id@JsonFormat(shape = JsonFormat.Shape.STRING)private Long categoryId;//菜品价格private BigDecimal price;//商品码private String code;//图片private String image;//描述信息private String description;//0 停售 1 起售private Integer status;//顺序private Integer sort;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)@JsonFormat(shape = JsonFormat.Shape.STRING)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)@JsonFormat(shape = JsonFormat.Shape.STRING)private Long updateUser;}

3 菜品和套餐的dao和service

建议自己写,很快,复制粘贴总会把实体类之类的写错。

@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}
@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}
public interface DishService extends IService<Dish> {
}
public interface SetmealService extends IService<Setmeal> {
}
@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper,Dish> implements DishService {
}@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper,Setmeal> implements SetmealService {
}

4 检查后删除,业务异常捕获

目标:当分类关联了菜品和套餐时,不允许删除。

跟进到IService的remove方法,通过比较器wrapper删除,参数改成Integer的话算重载,可以改:

代码实现:

我前面自己写的时候,没有用异常捕获,是在业务层根据不同情况返回不同数字,然后controller根据数字R.error("错误原因") 。用异常捕获也能实现,两种效果都一样,用异常捕获更规范

service:

    @Overridepublic Integer remove(Long id){LambdaQueryWrapper<Setmeal> wrapper1=new LambdaQueryWrapper<>();wrapper1.eq(Setmeal::getCategoryId,id);LambdaQueryWrapper<Dish> wrapper2=new LambdaQueryWrapper<>();wrapper2.eq(Dish::getCategoryId,id);log.info("套餐查询:{}",setmealService.getMap(wrapper1));log.info("菜品查询:{}",dishService.getMap(wrapper2));//查到有菜品或套餐使用这个分类if(setmealService.count(wrapper1)>0) return -1;if(dishService.count(wrapper2)>0) return -2;return categoryDao.deleteById(id)>0?1:0;}

    @DeleteMappingpublic R<String> remove(Long ids){log.info("要删除的id:{}",ids);int success = -3;success=categoryService.remove(ids);log.info("删除状态:{}",success);if(success==1)return R.success("删除成功");else if(success==0) return R.error("网络原因删除失败");else if(success==-1) return R.error("有套餐正在使用此分类");else if(success==-2)return R.error("有菜品正在使用此分类");else return R.error("未知错误");}

异常捕获方案:

service

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService{@Autowiredprivate DishService dishService;@Autowiredprivate SetmealService setmealService;/*** 根据id删除分类,删除之前需要进行判断* @param id*/@Overridepublic void remove(Long id) {LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();//添加查询条件,根据分类id进行查询dishLambdaQueryWrapper.eq(Dish::getCategoryId,id);int count1 = dishService.count(dishLambdaQueryWrapper);//查询当前分类是否关联了菜品,如果已经关联,抛出一个业务异常if(count1 > 0){//已经关联菜品,抛出一个业务异常throw new CustomException("当前分类下关联了菜品,不能删除");}//查询当前分类是否关联了套餐,如果已经关联,抛出一个业务异常LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();//添加查询条件,根据分类id进行查询setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId,id);int count2 = setmealService.count();if(count2 > 0){//已经关联套餐,抛出一个业务异常throw new CustomException("当前分类下关联了套餐,不能删除");}//正常删除分类super.removeById(id);}
}

controller

    @DeleteMappingpublic R<String> delete(Long id){log.info("删除分类,id为:{}",id);//categoryService.removeById(id);if(categoryService.remove(ids)) return R.success("删除成功");//这里也可以throw业务异常,但不建议,一般都是service抛出异常,controller返回R.error();else return R.error("删除失败");}

业务异常类:

/*** 自定义业务异常类*/
public class CustomException extends RuntimeException {//带参构造方法,重新设置异常信息public CustomException(String message){super(message);}
}

全局异常处理:

@RestControllerAdvice
//@ControllerAdvice(annotations = {RestController.class, Controller.class})
//@ResponseBody
@Slf4j
public class GlobalExceptionHandler {/*** 异常处理方法* @return*/@ExceptionHandler(SQLIntegrityConstraintViolationException.class)public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){log.error(ex.getMessage());if(ex.getMessage().contains("Duplicate entry")){String[] split = ex.getMessage().split(" ");String msg = split[2] + "已存在";return R.error(msg);}return R.error("未知错误");}/*** 异常处理方法* @return*/@ExceptionHandler(CustomException.class)public R<String> exceptionHandler(CustomException ex){log.error(ex.getMessage());return R.error(ex.getMessage());}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/194026.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于冠状病毒群体免疫优化的PNN网络5.测试结果6.参考文献7.Matlab代码 …

【kafka】使用docker启动kafka

1.环境准备 docker拉取zookeeper镜像 docker pull zookeeper:3.4.14 创建zookeeper容器&#xff0c;默认端口号为2181 docker run -d --name zookeeper -p 2181:2181 zookeeper:3.4.14 拉取kafka镜像 docker pull wurstmeister/kafka:2.12-2.3.1 创键kafka容器&#xff…

pom.xml格式化快捷键

在软件开发和编程领域&#xff0c;"格式化"通常指的是将代码按照一定的规范和风格进行排列&#xff0c;以提高代码的可读性和维护性。格式化代码有助于使代码结构清晰、统一&#xff0c;并符合特定的编码规范。 格式化可以包括以下方面&#xff1a; 缩进&#xff1a…

Windows安装多个版本的Java

在做持续集成CI/CD时&#xff0c;需要用到Jenkins&#xff0c;本人爱好使用各种最新版&#xff0c;down下来之后发现&#xff0c;新版只支持Java11以上的版本了&#xff01;&#xff01; 苦苦找了很久&#xff0c;找不到正规Java8版本的Jenkins安装包&#xff01; 干脆换个思路…

Typecho框架漏洞

这里说的框架漏洞只适用于1.2.0版本及以下的版本 这里说的漏洞是xss漏洞&#xff0c;学过渗透的应该都学过&#xff0c;我在这里就不过多阐述了&#xff0c;下面我们直接进入正题 直接在这个地方插入网址&#xff0c;后面再接上html代码即可&#xff0c;代码如下&#xff1a; …

【接口测试】最细Fiddle抓包辅助接口实战,抓包全过程总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、为什么需要抓包…

网页视频下载工具 iTubeGo mac中文版软件特色

iTubeGo YouTube Downloader mac是一款功能强大的YouTube视频下载工具。 iTubeGo YouTube Downloader mac软件特色 多种格式支持&#xff1a;iTubeGo YouTube Downloader可以将YouTube视频下载为多种常见的视频和音频格式&#xff0c;包括MP4、MP3、AVI、FLV、MOV、WMV等&…

系列十、你说你做过JVM调优和参数配置,请问如何盘点JVM系统的默认值?

一、JVM的参数类型 1.1、标配参数 java -versionjava -help 1.2、XX参数 1.2.1、Boolean类型 公式&#xff1a;-XX:或者- 某个属性值 表示开启、-表示关闭 # 是否打印GC收集细节 -XX:PrintGCDetails -XX:-PrintGCDetails# 是否使用串行垃圾收集器 -XX:UseSerialGC -XX:-UseS…

Flutter 中数据存储的四种方式

在 Flutter 中&#xff0c;存储是指用于本地和远程存储和管理数据的机制。以下是 Flutter 中不同存储选项的概述和示例。 Shared Preferences&#xff08;本地键值存储&#xff09; Shared Preferences 是一种在本地存储少量数据&#xff08;例如用户首选项或设置&#xff09…

AI工具合集

网站&#xff1a;未来百科 | 为发现全球优质AI工具产品而生 (6aiq.com) 如今&#xff0c;AI技术涉及到了很多领域&#xff0c;比如去水印、一键抠图、图像处理、AI图像生成等等。站长之家之前也分享过一些&#xff0c;但是在网上要搜索找到它们还是费一些功夫。 今天发现了一…

基于猕猴Spike运动解码的不同解码方法性能对比

公开数据集中文版详细描述 参考前文&#xff1a;https://editor.csdn.net/md/?not_checkout1&spm1011.2124.3001.6192神经元Spike信号分析 参考前文&#xff1a;https://blog.csdn.net/qq_43811536/article/details/134359566?spm1001.2014.3001.5501神经元运动调制分析 …

简历技术栈redis点

熟悉Redis常见的数据类型以及缓存问题&#xff0c;如缓存穿透、雪崩 、击穿等 Redis五种数据类型 Redis常用命令 查看所有 keys * 字符串类型string 常用命令 举例&#xff1a; 放置一个字符串数据到redis中&#xff0c;先为数据定义一个名称&#xff0c;比如name,age等&am…