26 Nisan 2021 Pazartesi

Bean Validation @Repeatable Anotasyonu

Giriş
Şu satırı dahil ederiz.
import java.lang.annotation.Repeatable;
Örnek
Elimizde şöyle bir kod olsun. Burada @Repeatable kullanılıyor. Bizim kendi kodumuz olan @ConditionalValidation anotasyonunun tekrar edebileceğini belirtiyor.  conditionalProperty alanı bean içindeki alan ismi, values bu alana atanabilecek değerler.
@Repeatable(ConditionalValidations.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ConditionalValidator.class})
public @interface ConditionalValidation {

    String message() default "Field is required.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    String conditionalProperty();

    String[] values();

    String[] requiredProperties();
}
Böylece anotasyonumuzu artık şöyle kullanabiliriz
@ConditionalValidation(
        conditionalProperty = "kind", values = {"PRIVATE"},
        requiredProperties = {"firstName", "lastName"},
        message = "First and last name are required for private partners.")
@ConditionalValidation(
        conditionalProperty = "kind", values = {"BUSINESS"},
        requiredProperties = {"name"},
        message = "Name is required for a business partner.")
public class Partner {
  @NotEmpty
  private String id;
  @NotNull
  private PartnerKind kind;
  private String name;
  private String firstName;
  private String lastName;
}
Validator için şöyle yaparız. Önce Validator nesnemizde anotasyonda tanımlı bilgileri alırız. 
public class ConditionalValidator implements
ConstraintValidator<ConditionalValidation, Object> {

private String conditionalProperty;
  private String[] requiredProperties;
  private String message;
  private String[] values;

  @Override
  public void initialize(ConditionalValidation constraint) {
    conditionalProperty = constraint.conditionalProperty();
    requiredProperties = constraint.requiredProperties();
    message = constraint.message();
    values = constraint.values();
  }

  ...
}
Daha sonra şöyle yaparız
@Override
public boolean isValid(Object object, ConstraintValidatorContext context) {
  try {
    Object conditionalPropertyValue = BeanUtils.getProperty(object,
conditionalProperty);
    if (doConditionalValidation(conditionalPropertyValue)) {
      return validateRequiredProperties(object, context);
    }
  } catch (NoSuchMethodException|InvocationTargetException|IllegalAccessException ex) {
    return false;
  }
  return true;
}
private boolean validateRequiredProperties(Object object,
ConstraintValidatorContext context)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  boolean isValid = true;
  for (String property : requiredProperties) {
    Object requiredValue = BeanUtils.getProperty(object, property);
    boolean isPresent = requiredValue != null && !isEmpty(requiredValue);
    if (!isPresent) {
      isValid = false;
      context.disableDefaultConstraintViolation();
      context
        .buildConstraintViolationWithTemplate(message)
        .addPropertyNode(property)
        .addConstraintViolation();
    }
  }
  return isValid;
}
private boolean doConditionalValidation(Object actualValue) {
  return Arrays.asList(values).contains(actualValue);
}

Hiç yorum yok:

Yorum Gönder