JavaBean Validation - Using constraints on constructor and method parameters

[Updated: Aug 11, 2017, Created: Sep 23, 2016]

We can do validations on constructor parameters or method parameters by placing the constraints just right before the parameters.


Using constraints on constructor parameter

We can validate constructor parameters before the constructor is invoked so that we can be sure that all preconditions are met before calling a constructor. For example:

The bean:

    public class User {
        private final String name;
        private final String phone;

        public User (@NotNull String name,
                     @NotNull
                     @Pattern(regexp = "(\\d){3,3}-\\d{3,3}-\\d{4,4}",
                     message = "must match 111-111-1111 format")
                     String phone) {
            this.name = name;
            this.phone = phone;
        }
      ....
    }

Performing validations

public class Test{
    public static void main (String[] args) throws NoSuchMethodException {

        javax.validation.Validator validator =  ....

        String userName = null;
        String userPhone = "223-223-222";

        ExecutableValidator executableValidator = validator.forExecutables();

        Set<ConstraintViolation<User>> constraintViolations =
                            executableValidator.validateConstructorParameters(
                              User.class.getConstructor(String.class, String.class),
                                                 new  Object[]{userName, userPhone});

        if (constraintViolations.size() > 0) {
            constraintViolations.stream().forEach(Test::printError);
        } else {
            User user = new User(userName, userPhone);
            System.out.println(user);
        }
    }

    private static void printError (
                        ConstraintViolation<User> violation) {
        System.out.println(violation.getPropertyPath() + " " + violation.getMessage());
    }
}

Output

    User.arg1 must match 111-111-1111 format
    User.arg0 may not be null


As saw in above example, ExecutableValidator is used for methods and constructors parameter/return values validations. It has methods of form validateXyz(..)



Using constraints on method parameters

Just like constrictors, we can also find out validation violations on method parameter before the method is invoked. That way we can make sure that all preconditions are satisfied before calling a method. For example:

The bean:

     public class Task {
        public void run (@Size(min = 3, max = 20) String name,
                         @NotNull Runnable runnable) {
            System.out.println("starting task synchronously: " + name);
            runnable.run();
        }
    }

Validations:

    Task task = new Task();
    String taskName = "a"; //"myTask"
    Runnable runnable = null; // ()-> System.out.println("task running");

    ExecutableValidator executableValidator = validator.forExecutables();
    Set<ConstraintViolation<Task>> violations =
                      executableValidator.validateParameters(task,
                           Task.class.getDeclaredMethod("run",
                           new Class[]{String.class, Runnable.class}),
                           new Object[]{taskName, runnable});

    if (violations.size() > 0) {
          violations.stream().forEach(MethodParamValidationExample::printError);
    } else {
           task.run(taskName, runnable);
    }
 

Output:

    run.arg0 size must be between 3 and 20
    run.arg1 may not be null


Example project

Dependencies and Technologies Used :

  • Hibernate Validator Engine 5.2.4.Final: Hibernate's Bean Validation (JSR-303) reference implementation.
  • Expression Language API 2.2 2.2.4
  • Expression Language 2.2 Implementation 2.2.4
  • JDK 1.8
  • Maven 3.0.4

Parameter Constrains Select All Download
  • parameter-validation
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also