代码优雅之道——断言 + Springboot统一异常处理

简介: 代码优雅之道 第二集

代码优雅之道第一集

1、为什么要这么做

在上一篇最后提到就是面对业务代码中出现异常的情况,如果不处理,则展示给用户的信息是非常不友好的。比如以下代码出现空指针时

那么前端得到的响应是啥样?

此外在业务代码中可能会用很多的校验,有的校验返回一些提示信息,有的校验可能需要抛出指定的异常。

通常我们使用try {...} catch {...} finally {...} 代码块来处理异常,而这些异常我们是不能直接展现给用户。所以对异常进行分类统一处理,减少冗余代码,使代码风格统一更优雅。

2、断言处理

像上图中一个代码块中会有很多的校验,而实际项目中非空或者一些业务判断都是很频繁的。我们来改造一下上图中的代码,使用断言后两行代码就解决了

到这里不用看源码大家肯定也已经猜到了,它肯定用的if(){}

是null就抛出异常,而state()却不一样,为false时抛出异常,所以这里的表达式填我们想要的结果。

用之前去Assert类中看一看,多用几次自然就熟练了,开发起来也会更加的快速。

实际项目中我们可能还需要调用其他服务暴露出来的接口,调用失败后抛出自定义的异常

此时我们也可以写个断言工具类

publicclassAssertUtil {
/*** 服务调用异常* @param expression* @param message*/publicstaticvoidisTrueServiceInvoke(booleanexpression, Stringmessage) {
if (!expression) {
thrownewServiceInvokeException(message);
        }
    }
}

那么这一类问题,都可以使用,解决了代码冗余问题

3、统一异常处理

通过以上描述我们也可以看出,项目中除了空指针这种异常,还有断言抛出的异常,还有自定义异常,对各种各样的异常统一处理,使得返回更加友好的信息。

主要通过 @RestControllerAdive 提升作用域,通过 @ExceptionHandler 注解来处理不同的异常。

importcom.example.assertdemo.common.exception.ServiceInvokeException;
importcom.example.assertdemo.constant.ResultCodeEnum;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.web.bind.annotation.ControllerAdvice;
importorg.springframework.web.bind.annotation.ExceptionHandler;
importorg.springframework.web.bind.annotation.ResponseBody;
@Slf4j@ControllerAdvicepublicclassGlobalExceptionHandler {
@ResponseBody@ExceptionHandler(NullPointerException.class)
publicApiResultnullPointerExceptionHandler(NullPointerExceptionexception) {
log.error(exception.getMessage());
returnApiResult.fail(ResultCodeEnum.SERVE_EXCEPTION);
    }
@ResponseBody@ExceptionHandler(ServiceInvokeException.class)
publicApiResultserviceInvokeExceptionHandler(ServiceInvokeExceptionexception){
log.error(exception.getMessage());
returnApiResult.fail(ResultCodeEnum.SERVE_EXCEPTION);
    }
}

返回的状态码和提示信息搞个枚举类

@GetterpublicenumResultCodeEnum{
/*** success*/SUCCESS(0,"操作成功"),
/*** fail*/FAIL(-1,"操作失败"),
/*** 参数错误:1001-1999*/PARAM_IS_INVALID(1001,"参数无效"),
PARAM_TYPE_ERROR(1002,"参数类型错误"),
/*** 业务错误:2001-2999*/TERMINATE_CONTRACT_FAIL(2001,"终止合同失败,请联系管理员"),
SERVE_EXCEPTION(3001,"当前服务出小差了,请联系管理员"),
    ;
/*** 状态码*/privatefinalintcode;
/*** 提示信息*/privatefinalStringmessage;
ResultCodeEnum(Integercode, Stringmessage){
this.code=code;
this.message=message;
    }
}


此时我们再去请求2、断言处理中的接口,这种提示就非常友好,不会给用户展示看不懂的一连串异常信息,还能让开发者及时定位到问题去处理。

4、断言类中的方法

说白了很多方法就是填入你希望的结果,比如isTrue(a==1,""),也就是我希望a等于1,如果不等于就抛出异常。

对象和类型断言

方法

说明

notNull()

对象是null抛出异常

isNull()

对象不是null抛出异常

isInstanceOf()

检查对象必须为另一个特定类型的实例

isAssignable()

检查类型

文本断言

方法

说明

hasLength()

只要不是null和空字符串就不会报异常

hasText()

增强检查条件,字符串至少包含一个非空白字符,可以使用hasText()方法

doesNotContain()

检查参数不包含特定子串

逻辑断言

方法

说明

isTrue()

条件为假抛出IllegalArgumentException 异常

state()

该方法与isTrue一样,但抛出IllegalStateException异常

Collection和map断言

方法

说明

Collection应用notEmpty()

Collection不是null并包含至少一个元素

map应用notEmpty()

检查map不null,并至少包含一个entry(key,value键值对)

数组断言

方法

说明

notEmpty()

可以检查数组不null,且至少包括一个元素

noNullElements()

确保数组不包含null元素

相关文章
|
3月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
558 1
Spring boot 使用mybatis generator 自动生成代码插件
|
3月前
|
Java 调度 流计算
基于Java 17 + Spring Boot 3.2 + Flink 1.18的智慧实验室管理系统核心代码
这是一套基于Java 17、Spring Boot 3.2和Flink 1.18开发的智慧实验室管理系统核心代码。系统涵盖多协议设备接入(支持OPC UA、MQTT等12种工业协议)、实时异常检测(Flink流处理引擎实现设备状态监控)、强化学习调度(Q-Learning算法优化资源分配)、三维可视化(JavaFX与WebGL渲染实验室空间)、微服务架构(Spring Cloud构建分布式体系)及数据湖建设(Spark构建实验室数据仓库)。实际应用中,该系统显著提升了设备调度效率(响应时间从46分钟降至9秒)、设备利用率(从41%提升至89%),并大幅减少实验准备时间和维护成本。
250 0
|
8月前
|
XML 前端开发 Java
SpringBoot整合Flowable【04】- 通过代码控制流程流转
本文介绍了如何使用Flowable的Java API控制流程流转,基于前文构建的绩效流程模型。首先,通过Flowable-UI导出模型文件并部署到Spring Boot项目中。接着,详细讲解了如何通过代码部署、启动和审批流程,涉及`RepositoryService`、`RuntimeService`和`TaskService`等核心服务类的使用。最后,通过实际操作演示了流程从部署到完成的全过程,并简要说明了相关数据库表的变化。本文帮助读者初步掌握Flowable在实际业务中的应用,后续将深入探讨更多高级功能。
1037 0
SpringBoot整合Flowable【04】-  通过代码控制流程流转
|
11月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
423 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
11月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
2438 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
10月前
|
缓存 监控 Java
|
10月前
|
缓存 监控 Java
|
11月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
108 2
|
11月前
|
消息中间件 Java 大数据
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
221 2
|
11月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
354 0