[英]@Notnull Spring Custom Annotation Validation with multiple field
如何編寫(類型級別注解)自定義注解以進行選擇驗證(許多屬性之一必須不為null)?
即使這個“問題”涉及面很廣,我也會給出一個答案,因為這里有我需要的代碼:
@Target(ElementType.TYPE)
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ChoiceValidator.class)
public @interface Choice {
String[] value();
boolean multiple() default false;
String message() default "{com.stackoverflow.validation.Choice.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
使用bean屬性訪問這里驗證:
public class ChoiceValidator implements ConstraintValidator<Choice, Object> {
private String[] properties;
private boolean allowMultiple;
@Override
public void initialize(Choice constraintAnnotation) {
if (constraintAnnotation.value().length < 2) {
throw new IllegalArgumentException("at least two properties needed to make a choice");
}
properties = constraintAnnotation.value();
allowMultiple = constraintAnnotation.multiple();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
try {
BeanInfo info = getBeanInfo(value.getClass());
long notNull = Stream.of(properties)
.map(property -> Stream.of(info.getPropertyDescriptors())
.filter(desr -> desr.getName().equals(property))
.findAny()
.orElse(null)
)
.map(prop -> getProperty(prop, value))
.filter(Objects::nonNull)
.count();
return allowMultiple ? notNull != 0 : notNull == 1;
} catch (IntrospectionException noBean) {
return false;
}
}
private Object getProperty(PropertyDescriptor prop, Object bean) {
try {
return prop.getReadMethod() == null ? null : prop.getReadMethod().invoke(bean);
} catch (ReflectiveOperationException noAccess) {
return null;
}
}
}
典型用法如下所示( lombok注釋可生成getter和setter):
@Data
@Choice({"one", "two"})
class OneOf {
private String one;
private String two;
private String whatever;
}
@Data
@Choice(value = {"one", "two"}, multiple = true)
class AnyOf {
private String one;
private String two;
}
但需要澄清的是:Stackoverflow是供開發人員交流知識的QA社區。 這是不是要問的地方“可以請你的代碼這對我來說免費的嗎?”。 所有有價值的貢獻者至少都首先嘗試解決問題,然后再提出詳細問題。 人們回答問題會花費他們的業余時間,而他們卻沒有得到報酬。 請提出具體問題並表示自己的努力,以表示尊重。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.