首页
/ Solon框架中实现自定义校验注解的分组校验功能

Solon框架中实现自定义校验注解的分组校验功能

2025-07-01 20:08:22作者:宗隆裙

在Java应用开发中,数据校验是一个非常重要的环节。Solon框架提供了强大的校验机制,不仅内置了多种常用校验注解,还支持开发者自定义校验注解。本文将详细介绍如何在Solon框架中为自定义校验注解实现分组校验功能。

分组校验的基本概念

分组校验是数据校验中的一个高级特性,它允许我们根据不同的业务场景对同一个对象应用不同的校验规则。例如:

  • 在创建用户时,需要校验所有必填字段
  • 在更新用户时,可能只需要校验部分字段
  • 在不同业务模块中,可能对同一字段有不同的校验要求

Solon框架内置的校验注解(如@NotNull、@Size等)都支持通过groups属性来指定校验分组。

自定义校验注解实现分组

要实现支持分组校验的自定义注解,需要以下几个步骤:

1. 定义校验注解

首先创建一个自定义注解,并添加groups属性:

import javax.validation.groups.Default;

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomCheck {
    String message() default "自定义校验失败";
    
    Class<?>[] groups() default {Default.class};
    
    // 其他自定义属性...
}

2. 实现校验逻辑

创建校验器类,实现Validator接口,并在校验方法中处理分组逻辑:

public class MyCustomValidator implements Validator<MyCustomCheck> {
    @Override
    public boolean isValid(MyCustomCheck anno, ValueStack stack, StringBuilder tmp) {
        // 获取当前校验上下文中的分组信息
        Class<?>[] activeGroups = ValidatorManager.getGroups(stack);
        
        // 检查当前校验是否属于活跃分组
        if(!isGroupMatch(anno.groups(), activeGroups)) {
            return true; // 不属于当前分组,跳过校验
        }
        
        // 实际的校验逻辑...
        Object val = stack.peek();
        return /* 你的校验条件 */;
    }
    
    private boolean isGroupMatch(Class<?>[] annoGroups, Class<?>[] activeGroups) {
        // 实现分组匹配逻辑
        // 如果注解没有指定groups,默认匹配Default分组
        if(annoGroups.length == 0) {
            annoGroups = new Class<?>[]{Default.class};
        }
        
        // 检查是否有交集
        for(Class<?> annoGroup : annoGroups) {
            for(Class<?> activeGroup : activeGroups) {
                if(annoGroup.isAssignableFrom(activeGroup)) {
                    return true;
                }
            }
        }
        
        return false;
    }
}

3. 注册校验器

在应用启动时注册自定义校验器:

@Configuration
public class Config {
    @Bean
    public void initValidator() {
        ValidatorManager.register(MyCustomCheck.class, new MyCustomValidator());
    }
}

使用分组校验

定义分组接口:

public interface CreateGroup {}
public interface UpdateGroup {}

在DTO中使用分组:

public class UserDto {
    @NotBlank(groups = {CreateGroup.class, UpdateGroup.class})
    private String username;
    
    @MyCustomCheck(groups = CreateGroup.class)
    private String password;
    
    // getters and setters
}

在控制器中指定校验分组:

@Controller
public class UserController {
    @Post
    @Mapping("/user/create")
    public Result create(@Validated(CreateGroup.class) UserDto user) {
        // 业务逻辑
    }
    
    @Post
    @Mapping("/user/update")
    public Result update(@Validated(UpdateGroup.class) UserDto user) {
        // 业务逻辑
    }
}

分组校验的高级用法

1. 默认分组

如果没有指定groups属性,默认使用javax.validation.groups.Default分组。

2. 多分组组合

可以同时指定多个分组:

@Validated({Group1.class, Group2.class})

3. 分组继承

分组可以是接口,支持继承关系:

public interface Group1 {}
public interface Group2 extends Group1 {}

这样在校验Group2时,也会执行标记为Group1的校验规则。

注意事项

  1. 分组校验的性能开销略大于普通校验,因为需要额外的分组匹配逻辑
  2. 在设计分组时,应该保持合理的粒度,避免分组过多导致维护困难
  3. 对于复杂的校验场景,可以考虑结合使用分组校验和条件校验

通过以上方式,我们可以在Solon框架中为自定义校验注解实现与内置校验注解相同的分组校验功能,从而满足不同业务场景下的灵活校验需求。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
27
11
docsdocs
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
466
3.47 K
nop-entropynop-entropy
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
10
1
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Java
65
19
flutter_flutterflutter_flutter
暂无简介
Dart
715
172
giteagitea
喝着茶写代码!最易用的自托管一站式代码托管平台,包含Git托管,代码审查,团队协作,软件包和CI/CD。
Go
23
0
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
203
81
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.26 K
695
rainbondrainbond
无需学习 Kubernetes 的容器平台,在 Kubernetes 上构建、部署、组装和管理应用,无需 K8s 专业知识,全流程图形化管理
Go
15
1
apintoapinto
基于golang开发的网关。具有各种插件,可以自行扩展,即插即用。此外,它可以快速帮助企业管理API服务,提高API服务的稳定性和安全性。
Go
22
1