Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Validate List of Strings for non empty elements

I have a model class which has list of Strings. The list can either be empty or have elements in it. If it has elements, those elements can not be empty. For an example suppose I have a class called QuestionPaper which has a list of questionIds each of which is a string.

class QuestionPaper{
private List<String> questionIds;
....
}

The paper can have zero or more questions. But if it has questions, the id values can not be empty strings. I am writing a micro service using SpringBoot, Hibernate, JPA and Java. How can I do this validation. Any help is appreciated.

For an example we need to reject the following json input from a user.

{ "examId": 1, "questionIds": [ "", " ", "10103" ] }

Is there any out of the box way of achieving this, or will I have to write a custom validator for this.

like image 981
Ravindra Ranwala Avatar asked Sep 15 '16 06:09

Ravindra Ranwala


People also ask

Is @valid and @validated the same?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.

What is the use of @validated annotation?

@Validated annotation is a class-level annotation that we can use to tell Spring to validate parameters that are passed into a method of the annotated class. @Valid annotation on method parameters and fields to tell Spring that we want a method parameter or field to be validated.

What does @valid do in Spring boot?

When Spring Boot finds an argument annotated with @Valid, it automatically bootstraps the default JSR 380 implementation — Hibernate Validator — and validates the argument. When the target argument fails to pass the validation, Spring Boot throws a MethodArgumentNotValidException exception.


1 Answers

Custom validation annotation shouldn't be a problem:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NotEmptyFieldsValidator.class)
public @interface NotEmptyFields {

    String message() default "List cannot contain empty fields";

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

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

}


public class NotEmptyFieldsValidator implements ConstraintValidator<NotEmptyFields, List<String>> {

    @Override
    public void initialize(NotEmptyFields notEmptyFields) {
    }

    @Override
    public boolean isValid(List<String> objects, ConstraintValidatorContext context) {
        return objects.stream().allMatch(nef -> nef != null && !nef.trim().isEmpty());
    }

}

Usage? Simple:

class QuestionPaper{

    @NotEmptyFields
    private List<String> questionIds;
    // getters and setters
}

P.S. Didn't test the logic, but I guess it's good.

like image 177
Branislav Lazic Avatar answered Sep 22 '22 14:09

Branislav Lazic