You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何根据type值条件性启用@Size注解校验?

动态条件校验实现方案(Spring Boot场景)

这个需求完全不需要创建单独类,有两种实用的实现方式:


方式一:自定义通用条件校验注解(适合多场景复用)

如果后续还有类似的条件校验需求,推荐用这种方式,灵活性更高:

1. 定义自定义校验注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SizeWhenTypeIsValidator.class)
public @interface SizeWhenTypeIs {
    String message() default "当指定字段匹配值时,目标字段长度不满足要求";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    String targetField(); // 需要校验的字段名
    String triggerField(); // 触发校验的条件字段名
    String triggerValue(); // 触发校验的字段值
    int min() default 0; // 最小长度
}

2. 实现注解对应的校验器

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;

public class SizeWhenTypeIsValidator implements ConstraintValidator<SizeWhenTypeIs, Object> {
    private String targetField;
    private String triggerField;
    private String triggerValue;
    private int min;

    @Override
    public void initialize(SizeWhenTypeIs constraintAnnotation) {
        this.targetField = constraintAnnotation.targetField();
        this.triggerField = constraintAnnotation.triggerField();
        this.triggerValue = constraintAnnotation.triggerValue();
        this.min = constraintAnnotation.min();
    }

    @Override
    public boolean isValid(Object obj, ConstraintValidatorContext context) {
        try {
            // 获取条件字段的值
            Field triggerFieldObj = obj.getClass().getDeclaredField(triggerField);
            triggerFieldObj.setAccessible(true);
            String typeValue = (String) triggerFieldObj.get(obj);

            // 不满足触发条件时,直接通过校验
            if (!triggerValue.equals(typeValue)) {
                return true;
            }

            // 满足触发条件时,校验目标字段长度
            Field targetFieldObj = obj.getClass().getDeclaredField(targetField);
            targetFieldObj.setAccessible(true);
            String nameValue = (String) targetFieldObj.get(obj);

            return nameValue != null && nameValue.length() >= min;
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("校验器反射获取字段失败", e);
        }
    }
}

3. 在目标类上使用注解

@SizeWhenTypeIs(
    targetField = "name",
    triggerField = "type",
    triggerValue = "Type 1",
    min = 3,
    message = "当type为Type 1时,name长度不能小于3"
)
public class CustomClass {
    private String name;
    private String type;

    // 省略getter、setter方法
}

方式二:类内@AssertTrue方法校验(适合简单单一场景)

如果只是这一个类需要这种校验,直接在类里写校验方法更简洁:

import javax.validation.constraints.AssertTrue;

public class CustomClass {
    private String name;
    private String type;

    @AssertTrue(message = "当type为Type 1时,name长度不能小于3")
    public boolean isNameValid() {
        // 仅当type为Type 1时,校验name的最小长度
        if ("Type 1".equals(type)) {
            return name != null && name.length() >= 3;
        }
        // 其他type值直接通过校验
        return true;
    }

    // 省略getter、setter方法
}

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 00:48:34