2025/12/31 4:13:48
网站建设
项目流程
网站开发有前途,网站开发文献综述范文,pageadmin下载,个人免费简历模板一、 背景#xff1a;标准注解不够用了怎么办#xff1f;
在 Spring Boot 开发中#xff0c;我们习惯了使用 NotNull, Size, Pattern 来校验参数。但是#xff0c;业务往往比这复杂得多。
场景举例#xff1a;
我们有一个用户保存接口#xff08;UserSaveReqVO#xff0…一、 背景标准注解不够用了怎么办在 Spring Boot 开发中我们习惯了使用NotNull,Size,Pattern来校验参数。但是业务往往比这复杂得多。场景举例我们有一个用户保存接口UserSaveReqVO既用于新增也用于修改。新增时id为空但password必须填。修改时id必填但password可以为空为空代表不修改密码。痛点如果直接在password字段上加NotBlank那么修改接口也会报错。如果不加新增接口就不安全。怎么解决二、 什么是 AssertTrueAssertTrue是 Bean Validation (Hibernate Validator) 提供的一个标准注解。字面含义断言为真。作用对象通常用于Boolean 类型的字段或返回 Boolean 类型的方法。校验规则如果值为true校验通过。如果值为false校验失败抛出异常并返回message中的错误信息。核心价值它允许我们在 DTO 内部编写一段 Java 代码来进行自定义的、跨字段的、带有业务逻辑的校验。三、 实战示例一行代码搞定“新增必填修改选填”我们不需要定义两个 DTO也不需要搞复杂的 Group直接在 VO 内部写一个方法即可。importcom.fasterxml.jackson.annotation.JsonIgnore;importio.swagger.v3.oas.annotations.media.Schema;importlombok.Data;importjavax.validation.constraints.AssertTrue;importjava.util.Objects;DataSchema(description用户保存请求 VO)publicclassUserSaveReqVO{Schema(description用户ID (新增为空修改必填))privateLongid;Schema(description账号)privateStringusername;Schema(description密码)privateStringpassword;// // 核心黑科技自定义逻辑校验// AssertTrue(message新增用户时密码不能为空)JsonIgnore// ⚠️ 坑点预警必须加这个否则会多出一个名为 passwordValid 的字段返回给前端publicbooleanisPasswordValid(){// 逻辑拆解// 1. 如果 id 不为空说明是“修改模式”。// 修改模式下对密码没要求直接返回 true (通过)。if(id!null){returntrue;}// 2. 如果 id 为空说明是“新增模式”。// 新增模式下密码必须有值。returnpassword!null!password.trim().isEmpty();}}Controller 使用方式完全不用改照常加Valid即可。PostMapping(/save)publicCommonResultBooleansaveUser(ValidRequestBodyUserSaveReqVOreqVO){// 如果校验失败这里进不来全局异常处理器会处理returnsuccess(userService.saveUser(reqVO));}四、 为什么它比 Validation Groups (分组校验) 更好很多教程会推荐使用groups属性来解决这个问题但在实战工程中AssertTrue 往往更胜一筹。1. 避免“注解地狱”与“类爆炸”Groups 方案你需要定义CreateGroup和UpdateGroup接口。然后字段上写Null(groupsCreate.class),NotNull(groupsUpdate.class)… 代码看起来很乱。AssertTrue 方案逻辑内聚在一个 Java 方法里if-else清晰易读。2. 代码高内聚 (High Cohesion)Groups 方案校验逻辑是割裂的。DTO 定义规则Controller 决定触发哪个 Group。如果你在 Controller 里忘了写Validated(CreateGroup.class)校验就失效了容易出 Bug。AssertTrue 方案校验逻辑完全封装在 DTO 内部。Controller 不需要关心是新增还是修改只要加个ValidDTO 自己会根据 ID 是否为空来判断该检查什么。3. 解决“跨字段依赖”问题这是 Group 做不到的。需求如果type是 “手机注册”则mobile必填如果type是 “邮箱注册”则email必填。AssertTrue直接写个if (type1) return mobile ! null;轻松搞定。五、 避坑指南在使用AssertTrue这种方法级校验时有两个细节必须注意方法名必须以is或get开头校验器是按照 JavaBean 规范来找方法的。建议使用isValid()或isXxxValid()。必须加上JsonIgnore这是最容易踩的坑。如果不加Jackson 序列化时会把这个方法当成一个属性比如passwordValid: true返回给前端或者导致 Swagger 文档里多出莫名其妙的字段。六、 总结简单校验非空、长度、正则直接用NotNull,Size等标准注解。场景区分新增/修改或跨字段逻辑A有值则B必填优先推荐使用AssertTrue 自定义方法。它让你的代码更内聚、更易读并且避免了 Controller 层繁琐的分组配置。