网站改版需要多少钱,网站推广总结,美容行业网站建设方案,wordpress文章调用函数参数校验这活儿#xff0c;写 Java 后端的同学肯定没少干。NotNull、Size、NotBlank 一把梭#xff0c;搞定大部分场景没啥问题。 但总有一些场景#xff0c;这些基本注解是真搞不定的。 比如你想根据某个字段的值来决定另一个字段要不要校验#xff0c;或者校验一个枚举值…参数校验这活儿写 Java 后端的同学肯定没少干。NotNull、Size、NotBlank一把梭搞定大部分场景没啥问题。但总有一些场景这些基本注解是真搞不定的。 比如你想根据某个字段的值来决定另一个字段要不要校验或者校验一个枚举值是不是合法的再或者校验的时候需要查一下数据库……遇到这种情况怎么办要么在 Service 层写一堆 if/else要么自定义ConstraintValidator代码散落在各处改起来还容易漏。SpEL Validator 是什么简单来说SpEL Validator 是一个基于 Spring Expression Language 的参数校验框架它不是要替代你熟悉的那些NotNull、NotBlank而是在 Jakarta Validation 的基础上做增强把原来搞不定的那些场景给补上。用过NotNull的同学上手 SpEL Validator 几乎零成本。直接看几个例子感受下条件式校验根据switchAudio的值决定是否校验audioContent只有当condition的表达式返回true时才会开启校验NotNull private Boolean switchAudio; SpelNotNull(condition #this.switchAudio true, message 语音内容不能为空) private Object audioContent;枚举值校验调用静态方法判断枚举值是否存在这里是个断言条件当assertTrue的表达式返回false时校验不通过SpelAssert(assertTrue T(cn.sticki.enums.ExampleEnum).getByCode(#this.testEnum) ! null , message 枚举值不合法) private Integer testEnum;调用 Spring Bean直接在表达式中调用已注入的 BeanSpelAssert(assertTrue exampleService.getUser(#this.userId) ! null, message 用户不存在) private Integer userId;怎么样够直观吧不用再到处翻 Validator 了打开类就能看到所有的校验规则。不过你可能也注意到了——这些 SpEL 表达式是写在字符串里的这意味着它们没有语法高亮、没有字段补全、字段名拼错了也没人提醒你得等到运行时才能发现。但是注意我要说但是了。我开发了一个配套的 IDEA 插件SpEL Validator Support。装上之后编写 SpEL 表达式也会有语法高亮、智能补全、CtrlClick 跳转、重命名同步、错误实时提醒全都有。实战演示准备工作引入依赖Spring Boot 3.x 用 jakarta 版dependency groupIdcn.sticki/groupId artifactIdspel-validator-jakarta/artifactId versionLatest Version/version /dependencySpring Boot 2.x 的同学把jakarta换成javax就行。然后去 IDEA 的 Plugins 里搜索安装SpEL Validator Support插件重启 IDEA。案例一条件式校验 智能补全这是示例项目中最基础的一个场景——SimpleExampleParamVoData SpelValid public class SimpleExampleParamVo { NotNull private Boolean switchAudio; SpelNotNull(condition #this.switchAudio true, message 语音内容不能为空) private Object audioContent; SpelAssert(assertTrue T(cn.sticki.validator.spel.example.enums.ExampleEnum).getByCode(#this.testEnum) ! null , message 枚举值不合法) private Integer testEnum; SpelAssert(assertTrue exampleService.getUser(#this.userId) ! null, message 用户不存在) private Integer userId; }这个类里就包含了三种之前不好处理的校验场景switchAudio为 true 时才校验audioContent通过静态方法校验枚举值是否合法调用 Spring Bean 查一下用户是否存在。全都写在注解里没有一行 if/else。装了插件之后你会发现 SpEL 表达式有了语法高亮字段名、方法调用、类型引用都有颜色区分。输入#this.的时候IDEA 会自动弹出当前类的所有字段。发起请求看一下校验效果// switchAudiotrue 但 audioContent 为空 → 校验不通过 {switchAudio: true, audioContent: null} // 响应{code: 400, message: audioContent 语音内容不能为空} // switchAudiofalse → audioContent 不校验通过 {switchAudio: false, audioContent: null} // 响应{code: 200, message: 成功}案例二分组校验 引用导航再看另一个更有意思的例子根据type分组校验不同的字段。在某些内容比较多的表单场景下可能会根据用户选择的不同类型然后展示不同的字段这时候就需要根据类型来分组校验不同的字段。Data SpelValid(spelGroups #this.type) public class GroupExampleParamVo { NotNull Pattern(regexp ^text|audio$) private String type; SpelNotNull(group Group.TEXT) private Object textContent; SpelNotNull(group Group.AUDIO) private Object audioContent; SpelNotNull // 未指定分组时默认被校验 private Integer other; static class Group { private static final String TEXT text; private static final String AUDIO audio; } }当type text时只有textContent和other会被校验当type audio时只有audioContent和other会被校验。分组逻辑写在注解里就完事了齐活。有了插件你可以CtrlClick表达式中的字段名直接跳转到字段定义。也可以在字段上右键Find Usages查看它在哪些 SpEL 表达式中被引用了。案例三调用 Spring Bean有时候校验逻辑不是简单的判空或比大小可能需要查一下数据库才能确定参数合不合法。这时候就需要在表达式里调用 Spring Bean 了。默认情况下SpEL Validator 不支持调用 Spring Bean需要先在启动类上加上EnableSpelValidatorBeanRegistrar注解开启 Bean 支持EnableSpelValidatorBeanRegistrar SpringBootApplication public class RestApplication { public static void main(String[] args) { SpringApplication.run(RestApplication.class, args); } }然后在你的 Service 里写个查询方法这里简单模拟一下Service public class ExampleService { public User getUser(int id) { User user new User(); user.setId(id); user.setName(阿杆); return user; } }现在就可以在校验注解中直接引用这个 Bean 了SpelAssert(assertTrue exampleService.getUser(#this.userId) ! null, message 用户不存在) private Integer userId;exampleService就是 Spring 容器里那个 Bean 的名字SpEL 原生语法。这里只是用简单例子演示一下调用方式。实际开发中你可以调用任何已注入的 Bean 方法来做校验查缓存查数据库都行。当然了校验里别搞太重的操作查个缓存差不多得了别搞成查了三张表还调了两个远程接口。有了插件的加持exampleService同样能被识别和高亮。如果你不小心写错了 Bean 名或字段名插件也会给你标红提醒。更多能力速览除了上面演示的场景SpEL Validator 还提供了丰富的约束注解注解说明对标 JakartaSpelAssert逻辑断言—SpelNotNull / SpelNull空值校验NotNull / NullSpelNotEmpty / SpelNotBlank非空校验NotEmpty / NotBlankSpelSize长度校验SizeSpelMin / SpelMax数值范围Min / MaxSpelDigits数字精度DigitsSpelFuture / SpelPast 等时间校验Future / Past所有注解都支持condition条件开关和group分组也支持国际化消息message {key}即可根据Accept-Language自动切换语言。如果有自定义约束注解的需求只要加上SpelConstraint元注解IDEA 插件同样能识别并提供智能支持。最后OK差不多就介绍到这里了。总结起来就是SpEL Validator 负责把校验能力补齐IDEA 插件负责让你写表达式的时候不再抓瞎两个搭一起用体验还是很舒服的。如果你的项目里经常碰到跨字段校验、条件式校验这类场景不妨试试看接入成本很低的。