package com.xxx.common.core.annotation; |
|
import javax.validation.ConstraintValidator; |
import javax.validation.ConstraintValidatorContext; |
import java.lang.reflect.Field; |
|
/** |
* @Author zibocoder |
* @Date 2026/04/13 |
* @Description 跨字段校验必填注解验证器 |
*/ |
public class CrossFieldRequiredValidator implements ConstraintValidator<CrossFieldRequired, Object> { |
// 被依赖的字段 |
private String dependField; |
// 被依赖字段的期望值 |
private String expectedValue; |
// 目标字段 |
private String targetField; |
// 触发方式 |
private CrossFieldRequired.TriggerType triggerType; |
|
@Override |
public void initialize(CrossFieldRequired constraintAnnotation) { |
this.dependField = constraintAnnotation.dependField(); |
this.expectedValue = constraintAnnotation.expectedValue(); |
this.targetField = constraintAnnotation.targetField(); |
this.triggerType = constraintAnnotation.triggerType(); |
} |
|
@Override |
public boolean isValid(Object value, ConstraintValidatorContext context) { |
if (value == null) { |
return true; |
} |
|
try { |
Field dependFld = getField(value.getClass(), dependField); |
if (dependFld == null) { |
return true; |
} |
dependFld.setAccessible(true); |
Object dependValue = dependFld.get(value); |
|
// 是否应该校验 |
boolean shouldValidate = false; |
if (triggerType == CrossFieldRequired.TriggerType.NOT_EMPTY) { |
shouldValidate = dependValue != null && !dependValue.toString().trim().isEmpty(); |
} else if (triggerType == CrossFieldRequired.TriggerType.NOT_EQUALS) { |
shouldValidate = dependValue != null && !expectedValue.equals(dependValue.toString()); |
} else if (triggerType == CrossFieldRequired.TriggerType.EQUALS) { |
shouldValidate = dependValue != null && expectedValue.equals(dependValue.toString()); |
} |
|
if (shouldValidate) { |
Field targetFld = getField(value.getClass(), targetField); |
if (targetFld == null) { |
return true; |
} |
targetFld.setAccessible(true); |
Object targetValue = targetFld.get(value); |
|
if (isEmpty(targetValue)) { |
context.disableDefaultConstraintViolation(); |
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()) |
.addPropertyNode(targetField) |
.addConstraintViolation(); |
return false; |
} |
} |
return true; |
} catch (Exception e) { |
return true; |
} |
} |
|
/** |
* 判断对象是否为空 |
* |
* @param value 对象 |
* @return true:为空 false:不为空 |
*/ |
private boolean isEmpty(Object value) { |
if (value == null) { |
return true; |
} |
if (value instanceof String) { |
return ((String) value).trim().isEmpty(); |
} |
return false; |
} |
|
/** |
* 递归查找字段,支持继承场景 |
* |
* @param clazz 类 |
* @param fieldName 字段名 |
* @return 字段 |
*/ |
private Field getField(Class<?> clazz, String fieldName) { |
while (clazz != null) { |
try { |
return clazz.getDeclaredField(fieldName); |
} catch (NoSuchFieldException e) { |
clazz = clazz.getSuperclass(); |
} |
} |
return null; |
} |
} |
|