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

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

2025-07-01 17:12:48作者:宗隆裙

在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框架中为自定义校验注解实现与内置校验注解相同的分组校验功能,从而满足不同业务场景下的灵活校验需求。

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