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
相关产品推荐
相关产品推荐

