分组校验(group validation)允许在不同的场景下对同一个实体类应用不同的校验规则。例如,在新增数据和更新数据时,可能需要对某些字段的校验规则进行调整。以下是分组校验的具体实现步骤:
一、定义分组接口
创建空的标记接口(仅用于分组标识):
// 新增时的校验分组 public interface creategroup {} // 更新时的校验分组 public interface updategroup {}
二、在实体类中指定分组
在字段的校验注解中,通过 groups
属性指定所属分组:
public class user { @notblank(message = "用户id不能为空", groups = updategroup.class) private string id; @notblank(message = "用户名不能为空", groups = creategroup.class) private string username; @size(min = 6, max = 20, message = "密码长度需在6到20位之间", groups = {creategroup.class, updategroup.class}) private string password; // 省略getter和setter }
id
字段:仅在updategroup
分组下校验(更新时必须校验)。username
字段:仅在creategroup
分组下校验(新增时必须校验)。password
字段:在creategroup
和updategroup
分组下均校验(新增和更新时都校验)。
三、在controller中指定校验分组
在controller方法参数上使用 @validated
注解(注意是 spring 的注解,而非 @valid
),并指定分组:
@restcontroller public class usercontroller { // 新增用户(校验 creategroup 分组) @postmapping("/users") public string createuser(@validated(creategroup.class) @requestbody user user) { return "用户新增成功"; } // 更新用户(校验 updategroup 分组) @putmapping("/users/{id}") public string updateuser(@validated(updategroup.class) @requestbody user user) { return "用户更新成功"; } }
四、全局异常处理
分组校验失败会抛出 constraintviolationexception
,需在全局异常处理器中捕获:
@restcontrolleradvice public class globalexceptionhandler { @responsestatus(httpstatus.bad_request) @exceptionhandler(constraintviolationexception.class) public map<string, object> handleconstraintviolationexception(constraintviolationexception ex) { map<string, string> errors = new hashmap<>(); ex.getconstraintviolations().foreach(violation -> { string field = violation.getpropertypath().tostring(); string message = violation.getmessage(); errors.put(field, message); }); return map.of( "code", httpstatus.bad_request.value(), "message", "参数校验失败", "data", errors ); } }
五、测试示例
1. 新增用户(触发 creategroup 分组校验)
请求:
post /users content-type: application/json { "password": "12345" }
响应:
{ "code": 400, "message": "参数校验失败", "data": { "username": "用户名不能为空", "password": "密码长度需在6到20位之间" } }
2. 更新用户(触发 updategroup 分组校验)
请求:
put /users/123 content-type: application/json { "password": "12345" }
响应:
{ "code": 400, "message": "参数校验失败", "data": { "id": "用户id不能为空", "password": "密码长度需在6到20位之间" } }
六、分组校验的高级用法
1. 多分组组合校验
可以在 @validated
中同时指定多个分组:
@validated({creategroup.class, anothergroup.class})
2. 默认分组
如果字段未指定 groups
属性,则默认属于 default
分组。可以通过 @validated
的 value
属性同时包含默认分组:
@validated(value = {updategroup.class, default.class})
3. 继承分组
分组接口可以继承其他接口,形成层级关系:
public interface advancedgroup extends creategroup {}
七、分组校验 vs 多个dto
方案 | 优点 | 缺点 |
---|---|---|
分组校验 | 避免创建多个相似dto,减少冗余代码 | 实体类可能包含不同场景的注解 |
多个dto | 职责单一,结构清晰 | 需要维护多个dto类 |
总结
通过分组校验,可以灵活控制不同场景下的校验规则,避免为每个场景创建单独的dto类。关键步骤:
定义分组接口。在实体类字段的校验注解中指定 groups
。在controller方法参数上使用 @validated(分组.class)
。全局捕获 constraintviolationexception
并返回自定义错误。
到此这篇关于springboot的实体类字段校验的分组校验具体实现步骤的文章就介绍到这了,更多相关springboot分组校验内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论