Home > Blockchain >  Validating field values in a Java POJO
Validating field values in a Java POJO

Time:11-05

Use Case:

Let's assume this is my POJO:

class Sample{
    
    String field1;

    String field2;

    double field3;

    LocalDateTime field4;

    LocalDateTime field5;

    //...getters, setters and parameterised constructor
}

I am reading certain values from an external file and creating a POJO using a parameterised constructor. All the fields have certain validation constraints for them.

What I am looking for is a way for those constraints to be evaluated automatically when I am creating an object using the parameterised constructor. If one or more validation constraints fail, it should throw an error.

What I have tried so far:

I have tried the Bean Validation approach in Spring by creating my own annotation and validator. The code is below:

POJO

@ValidChecker(groups = Default.class)
class Sample{
    
    String field1;

    String field2;

    double field3;

    LocalDateTime field4;

    LocalDateTime field5;

    //...getters, setters and parameterised constructor
}

ValidChecker Annotation

@Constraint(validatedBy = DataValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidChecker {

    String message() default "Data is not valid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

DataValidator.java

@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT)
public class DataValidator implements ConstraintValidator<ValidChecker, ValidationData> {

    @Override
    public void initialize(ValidChecker constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(ValidationData validationData, ConstraintValidatorContext constraintValidatorContext) {

        if (validationData == null) {
            return false;
        }

        if (BigDecimal.valueOf(validationData.getField3()).scale() != 2) {
            return false;
        }

        if (validationData.getField5().isBefore(validationData.getField4())) {
            return false;
        }

        return true;
    }
}

The above code didn't work.

Suggestions Needed

  1. Problem with the above approach
  2. Alternate approach using Spring
  3. Alternate approach by using some third party library

I looked quite a bit but couldn't find an approach without Spring bean validation. Can someone please help?

CodePudding user response:

You could use the Bean Validation API directly in your constructor:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Sample>> violations = validator.validate(this);
if (!violations.isEmpty()) {
    throw new ConstraintViolationException(violations);
}
  • Related