这是一套几乎无敌的参数校验组件!SpEL Validator 预览版发布
前言
大家好,我是阿杆,不是阿轩。
参数校验这个东西,很多情况下都是比较简单的,用 @NotNull
、@Size
等注解就可以解决绝大多数场景,但也有一些场景是这些基本注解解决不了的,只能用一些其他的方式处理,这样就导致参数校验变成了多层,其实是不利于代码维护的。
于是乎,我写了一套几乎可以满足任何场景的参数校验组件,名为 SpEL Validator ,安利给大家。
💡 它解决了什么问题?
-
枚举值字段校验:
@SpelAssert(assertTrue = " T(cn.sticki.enums.UserStatusEnum).getByCode(#this.userStatus) != null ", message = "用户状态不合法") private Integer userStatus;
-
多字段联合校验:
@NotNull private Integer contentType; @SpelNotNull(condition = "#this.contentType == 1", message = "语音内容不能为空") private Object audioContent; @SpelNotNull(condition = "#this.contentType == 2", message = "视频内容不能为空") private Object videoContent;
-
复杂逻辑校验,调用静态方法:
// 中文算两个字符,英文算一个字符,要求总长度不超过 10 // 调用外部静态方法进行校验 @SpelAssert(assertTrue = "T(cn.sticki.util.StringUtil).getLength(#this.userName) <= 10", message = "用户名长度不能超过10") private String userName;
-
调用 Spring Bean(需要使用 @EnableSpelValidatorBeanRegistrar 开启Spring Bean支持):
// 这里只是简单举例,实际开发中不建议这样判断用户是否存在 @SpelAssert(assertTrue = "@userService.getById(#this.userId) != null", message = "用户不存在") private Long userId;
-
更多使用场景,欢迎探索和补充!
📝 特点
- 强大的参数校验功能,几乎支持所有场景下的参数校验。
- 扩展自 javax.validation 包,只新增不修改,无缝集成到项目中。
- 基于 SpEL(Spring Expression Language) 表达式,支持复杂的校验逻辑。
- 支持调用 Spring Bean,可在表达式中使用注入过的 Spring Bean。
- 校验时基于整个对象,支持对象内字段间的校验逻辑。
- 支持自定义校验注解,可根据业务需求自定义校验逻辑。
- 无需额外的异常处理,校验失败时会上报到 javax.validation 的异常体系中。
- 简单易用,使用方式几乎与 javax.validation 一致,学习成本低,上手快。
🎈 环境
目前仅测试了 JDK8 环境,理论上来说 JDK8+ 应该都是支持的。
📦 快速开始
-
添加依赖
Latest Version: 0.2.0-beta
<dependency> <groupId>cn.sticki</groupId> <artifactId>spel-validator</artifactId> <version>Latest Version</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate-validator.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-starter-web.version}</version> </dependency>
-
在接口参数上使用
@Valid
或@Validated
注解@RestController @RequestMapping("/example") public class ExampleController { /** * 简单校验示例 */ @PostMapping("/simple") public Resp<Void> simple(@RequestBody @Valid SimpleExampleParamVo simpleExampleParamVo) { return Resp.ok(null); } }
-
在实体类上使用
@SpelValid
注解,同时在需要校验的字段上使用@SpelNotNull
等约束注解@Data @SpelValid public class SimpleExampleParamVo { @NotNull private Boolean switchAudio; /** * 当 switchAudio 为 true 时,校验 audioContent,audioContent 不能为null */ @SpelNotNull(condition = "#this.switchAudio == true", message = "语音内容不能为空") private Object audioContent; }
-
添加全局异常处理器,处理校验异常
@RestControllerAdvice public class ControllerExceptionAdvice { @ExceptionHandler({BindException.class, MethodArgumentNotValidException.class}) public Resp<Void> handleBindException(BindException ex) { String msg = ex.getFieldErrors().stream() .map(error -> error.getField() + " " + error.getDefaultMessage()) .reduce((s1, s2) -> s1 + "," + s2) .orElse(""); return new Resp<>(400, msg); } }
-
发起请求,即可看到校验结果
-
示例一:@SpelNotNull 校验不通过
请求体:
{ "switchAudio": true, "audioContent": null }
响应体
{ "code": 400, "message": "audioContent 语音内容不能为空", "data": null }
-
示例二:校验通过
请求体
{ "switchAudio": false, "audioContent": null }
响应体
{ "code": 200, "message": "成功", "data": null }
-
示例三:@NotNull 校验不通过
请求体
{ "switchAudio": null, "audioContent": null }
响应体
{ "code": 400, "message": "switchAudio 不能为null", "data": null }
-
📖 使用指南
注意:本组件的目的不是代替
javax.validation
的校验注解,而是作为一个扩展,方便某些场景下的参数校验。能够使用javax.validation
的场景就不要使用spel-validator
,因为spel-validator
会有一定的性能损耗。
开启约束校验
需要满足以下两个条件,才会对带注解的元素进行校验:
- 在接口参数上使用
@Valid
或@Validated
注解 - 在实体类上使用
@SpelValid
注解
如果只满足第一个条件,那么只会对带 @NotNull
、@NotEmpty
、@NotBlank
等注解的元素进行校验。
如果只满足第二个条件,那么不会对任何元素进行校验。
这是因为 @SpelValid
注解是基于 javax.validation.Constraint
实现的,只有在 @Valid
或 @Validated
注解的支持下才会生效。 而 spel-validator
提供的约束注解是基于 @SpelValid
进行扫描校验的,只有在 @SpelValid
注解生效的情况下才会执行约束校验。
使用约束注解
目前支持的约束注解有:
注解 | 说明 | 对标 javax.validation |
---|---|---|
@SpelAssert | 逻辑断言校验 | 无 |
@SpelNotNull | 非 null 校验 | @NotNull |
@SpelNotEmpty | 集合、字符串、数组大小非空校验 | @NotEmpty |
@SpelNotBlank | 字符串非空串校验 | @NotBlank |
@SpelNull | 必须为 null 校验 | @Null |
@SpelSize | 集合、字符串、数组长度校验 | @Size |
每个约束注解都包含三个默认的属性:
message
:校验失败时的提示信息。group
:分组条件,支持 SpEL 表达式,当分组条件满足时,才会对带注解的元素进行校验。condition
:约束开启条件,支持 SpEL 表达式,当 表达式为空 或 计算结果为true 时,才会对带注解的元素进行校验。
调用 Spring Bean
默认情况下,解析器无法识别 SpEL 表达式中的 Spring Bean。
如果需要在 SpEL 表达式中调用 Spring Bean,需要在启动类上添加 @EnableSpelValidatorBeanRegistrar
注解, 开启 Spring Bean 支持。
@EnableSpelValidatorBeanRegistrar @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
自定义约束注解
- 在注解上使用
@SpelConstraint
,并指定验证器。 - 然后给注解添加上三个固定的字段 message 、group、condition。
- 实现验证器
具体实现方式可以参考官方文档。
如果你使用过 javax.validation
的自定义约束注解,那么你会发现 SpEL Validator
的自定义约束注解几乎与 javax.validation
一致。
📦 示例项目
我也写了一个简单的示例项目,有一些基本的使用方法:
最后
贴一下GitHub地址:https://github.com/stick-i/spel-validator (顺手点个star呀~)
欢迎大家进行体验,有任何疑问欢迎一起讨论。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Docker 27.3.0 发布
Docker 27.3.0 现已发布,具体更新内容如下: Bug fixes and enhancements 向守护进程选项添加一个--feature标志。moby/moby#48487 更新了--gpus=0标志的处理以与 NVIDIA 容器运行时保持一致。moby/moby#48483(docker/cli#5432) 支持 WSL2 镜像模式网络使用接口loopback0接受来自 Windows host 的数据包。moby/moby#48514 修复了在运行--iptables=false,ip6tables=true (默认) 时,IPv4 桥接网络上的容器之间无法通信的问题,该防火墙在br_netfilter内核模块未正常加载的主机上对转发的数据包设置了 DROP 规则。moby/moby#48511 CLI:修复了docker volume update命令在没有传递 argument/volume的情况下会导致 CLI 出现 panic 的问题。docker/cli#5426 CLI:在 Windows 上的 WSL 环境中运行时正确报告 metrics。[docke...
- 下一篇
TextSearcher 1.8.9 已经发布,文本批量搜索工具
TextSearcher 1.8.9 已经发布,文本批量搜索工具 此版本主要更新了主界面UI,同时对核心功能进行了小幅优化: 简化了主界面布局网格(不改变主界面外观),提升UI渲染速度; 使用JTextPane代替JTextArea,以期在未来增加更加丰富的自定义文本功能; 读取失败时,主界面会以红字提示; 优化了搜索结果索引逻辑; 增加了对csv文件的支持 详情查看:https://gitee.com/qw3670/text-searcher/releases/1.8.9
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS6,CentOS7官方镜像安装Oracle11G
- Mario游戏-低调大师作品
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果