This example creates a new constraint annotation to validate constructor return value.
package com.logicbig.example;
import javax.validation.*;
import javax.validation.executable.ExecutableValidator;
import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Set;
public class ConstructorReturnValidationExample {
public static class Order {
private final BigDecimal price;
private final BigDecimal quantity;
@ValidOrder
public Order (BigDecimal price, BigDecimal quantity) {
this.price = price;
this.quantity = quantity;
}
public BigDecimal getPrice () {
return price;
}
public BigDecimal getQuantity () {
return quantity;
}
public BigDecimal getTotalPrice () {
return (price != null && quantity != null ?
price.multiply(quantity) : BigDecimal.ZERO)
.setScale(2, RoundingMode.CEILING);
}
}
public static void main (String[] args) throws NoSuchMethodException {
Order order = new Order(new BigDecimal(4.5), new BigDecimal(10));
Constructor<Order> constructor =
Order.class.getConstructor(BigDecimal.class, BigDecimal.class);
Validator validator = getValidator();
ExecutableValidator executableValidator = validator.forExecutables();
Set<ConstraintViolation<Order>> constraintViolations =
executableValidator.validateConstructorReturnValue(constructor, order);
if (constraintViolations.size() > 0) {
constraintViolations.stream().forEach(
ConstructorReturnValidationExample::printError);
} else {
//proceed using order
System.out.println(order);
}
}
private static Validator getValidator(){
Configuration<?> config = Validation.byDefaultProvider().configure();
ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();
factory.close();
return validator;
}
private static void printError (
ConstraintViolation<Order> violation) {
System.out.println(violation.getPropertyPath() + " " + violation.getMessage());
}
@Target({ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = OrderValidator.class)
@Documented
public static @interface ValidOrder {
String message () default "total price must be 50 or greater for online order. " +
"Found: ${validatedValue.totalPrice}";
Class<?>[] groups () default {};
Class<? extends Payload>[] payload () default {};
}
public static class OrderValidator implements ConstraintValidator<ValidOrder, Order> {
@Override
public void initialize (ValidOrder constraintAnnotation) {
}
@Override
public boolean isValid (Order order, ConstraintValidatorContext context) {
if (order.getPrice() == null || order.getQuantity() == null) {
return false;
}
return order.getTotalPrice()
.compareTo(new BigDecimal(50)) >= 0;
}
}
}
Output
Order.<return value> total price must be 50 or greater for online order. Found: 45.00
Original Post