Spring Validate List of Strings for non empty elements

24,597

Solution 1

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.

Solution 2

I just had similar case to solve

class QuestionPaper {

    @NotEmpty
    private List<@NotBlank String> questionIds;

    // getters and setters
}

Solution 3

These might suffice the need, if it is only on null or empty space.

@NotNull, @Valid, @NotEmpty

You can check with example. Complete set of validations - JSR 303 give an idea which suits the requirement.

Solution 4

If List is of Integers, then go as below

class QuestionPaper {

    @NotEmpty
    private List<@Min(0) Integer> questionIds;

    // getters and setters
}

Solution 5

!CollectionUtils.isEmpty(questionIds) 
   && !questionIds.stream.anyMatch(StringUtils::isEmpty())
Share:
24,597
Ravindra Ranwala
Author by

Ravindra Ranwala

I am a full stack developer who always love good design, clean code and unit tests. I am interested in Java, Algorithms, Data structures, Design Patterns, Object-Oriented Analysis and Design, Concurrency patterns, Multi threading, cryptography, Asynchronous programming, Parallel and Distributed Computing, UML, Type systems, Generics, Regular Expressions, C++, React, redux and es6.

Updated on September 03, 2021

Comments

  • Ravindra Ranwala
    Ravindra Ranwala over 2 years

    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.

  • Ravindra Ranwala
    Ravindra Ranwala over 7 years
    I have already tried, but these are not recursively applied to the list elements, rather it is enforced to the list. Thanks for the reply though. :)
  • Ravindra Ranwala
    Ravindra Ranwala over 7 years
    This also seems to work, List<String> questionIds = Arrays.asList("1000", "", " "); if (!questionIds.contains(null) && !questionIds.contains("")) { System.out.println("Valid List !!!!"); } else { System.out.println("Invalid List!!!!"); } My concern is how to add this to spring validator.
  • Journeycorner
    Journeycorner over 7 years
    I am not sure whether or not Bean Validation works on references
  • Zarremgregarrok
    Zarremgregarrok over 5 years
    The validation looks like it would crash on nef==null
  • Vickie Jack
    Vickie Jack about 4 years
    I edit the code like below and it works perfect: @Override public boolean isValid(List<String> objects, ConstraintValidatorContext context) { if (objects == null || objects.isEmpty()) return false; return objects.stream().allMatch(nef -> nef != null && !nef.trim().isEmpty()); }
  • rios0rios0
    rios0rios0 about 2 years
    It actually triggers an error 500 that can't be handled. "org.springframework.beans.NotReadablePropertyException". Example of message: "JSR-303 validated property XYZ does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)"
  • rios0rios0
    rios0rios0 about 2 years
    Correcting my own comment. It actually works. But, to do this answer in a proper way, you need BEFORE do this: stackoverflow.com/a/44064198/10746857.
  • rios0rios0
    rios0rios0 about 2 years
    Overengineering I guess. You can simply use the already existing annotations.