Keeping Your Data Sane with Bean Validation 2.0

Keeping Your Data Sane with Bean Validation 2.0

-- Presented at JavaOne 2017 --

Rich UIs, schemaless data stores, REST-based APIs—the need for powerful data validation is greater than ever. The Bean Validation standard is here to help, defining a rich validation API based on annotations.

Bean Validation 2.0 (JSR 380) makes validation even more expressive, leveraging Java 8 features such as type and repeatable annotations or default methods. This opens up exciting opportunities for Bean Validation, such as List. Part of Java EE 8, Bean Validation 2.0 can be used on Java SE too.

This code-centric session explores many of the new features right in the IDE. Find out how Bean Validation integrates with specs such as JAX-RS and how to implement your own constraints, ensuring that your data is sane at all times.

8e25c0ca4bf25113bd9c0ccc5d118164?s=128

Gunnar Morling

October 05, 2017
Tweet

Transcript

  1. Keeping Your Data Sane with Bean Validation 2.0 Gunnar Morling

    @gunnarmorling 1
  2. Agenda What is Bean Validation? What's new in Bean Validation

    2.0? Questions 2
  3. Gunnar Morling Open source software engineer at Red Hat Debezium

    Hibernate Spec Lead for Bean Validation 2.0 Other projects: ModiTect, MapStruct gunnar@hibernate.org @gunnarmorling http://in.relation.to/gunnar-morling/ 3
  4. What is Bean Validation? "Constrain once, validate everywhere" Constraints for

    JavaBeans Validation via API or automatically ​ JPA JSF, Spring MVC, GWT JAX-RS Extensible (custom constraints) BV 1.1: ​ method validation 4
  5. Demo 5

  6. Bean Validation 2.0 - JSR 380 Benefit from new Java

    8 language features Support for API extensions 6
  7. Use Case: Different Passwords for Different Roles @Size.List({ @Size(min =

    8, group = Default.class), @Size(min = 12, group = Admin.class) }) private char[] password = ...; 7
  8. Use Case: Different Passwords for Different Roles @Size.List({ @Size(min =

    8, group = Default.class), @Size(min = 12, group = Admin.class) }) private char[] password = ...; @Size(min = 8, group = Default.class) @Size(min = 12, group = Admin.class) private char[] password = ...; 8
  9. Use Case: Ensure Non-Empty Collection Elements private List<String> names; 9

  10. Use Case: Ensure Non-Empty Collection Elements private List<String> names; @NotEmpty

    private List<String> names; 10
  11. Use Case: Ensure Non-Empty Collection Elements private List<String> names; @OnElements(constraint=@NotEmpty)

    private List<String> names; 11
  12. Use Case: Ensure Non-Empty Collection Elements private List<String> names; private

    List<@NotEmpty String> names; @OnElements(constraint=@NotEmpty) private List<String> names; 12
  13. Use Case: Ensure Non-Empty Collection Elements private List<String> names; private

    List<@NotEmpty @Pattern(regexp="[a-zA-Z]*") String> names; @OnElements(constraint=@NotEmpty) private List<String> names; 13
  14. private List<@NotEmpty @Pattern(regexp="[a-zA-Z]*") String> names; Use Case: Ensure Non-Empty Collection

    Elements private List<String> names; @NotEmpty private List<@NotEmpty String> names; @OnElements(constraint=@NotEmpty) private List<String> names; 14
  15. @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Repeatable(List.class)

    @Documented @Constraint(validatedBy = { }) public @interface Size { ... } Type Annotations (JSR 308) New element type TYPE_USE 15
  16. Cascaded Validation @Valid private List<Address> addresses; 16

  17. Cascaded Validation @Valid private List<Address> addresses; private List<@Valid Address> addresses;

    17
  18. Cascaded Validation @Valid private List<Address> addresses; private List<@Valid Address> addresses;

    private Map<@Valid Comment, Integer> scorePerComment; 18
  19. Cascaded Validation @Valid private List<Address> addresses; private List<@Valid Address> addresses;

    private Map<@Valid Comment, Integer> scorePerComment; private Map<@Valid AddressType, List<@Valid Address>> addressesByType; 19
  20. Further Supported Containers Optional, OptionalInt, OptionalLong, OptionalDouble JavaFX's property types

    Optional<@Email String> getEmail() { ... }; 20
  21. Custom Containers Specific collection types (e.g. Google Guava) Other JVM

    languages (Ceylon, Scala etc.) Enabled via Extractor SPI private Table<Year, String, Integer> revenuePerYearAndCategory; 21
  22. private Table<Year, String, Integer> revenuePerYearAndCategory; private Table<Year, String, @Positive Integer>

    revenuePerYearAndCategory; Custom Containers Specific collection types (e.g. Google Guava) Other JVM languages (Ceylon, Scala etc.) Enabled via Extractor SPI 22
  23. Demo 23

  24. Use Case: Delivery Date in the Future @Past/@Future supported for

    JSR 310 types: java.time.LocalDateTime, ZonedDateTime etc. @Future private LocalDate deliveryDate = LocalDate.of( 2017, Month.MAY, 12 ); 24
  25. Use Case: Delivery Date in the Future @Past/@Future supported for

    JSR 310 types: java.time.LocalDateTime, ZonedDateTime etc. @FutureOrPresent private LocalDate deliveryDate = LocalDate.of( 2017, Month.MAY, 12 ); @Future private LocalDate deliveryDate = LocalDate.of( 2017, Month.MAY, 12 ); 25
  26. Use Case: Testing ValidatorFactory vf = Validation.byDefaultProvider() .configure() .clockProvider( new

    FixedClockProvider( ZonedDateTime.of( 2016, 6, 15, 0, 0, 0, 0, ZoneId.of( "Europe/Paris" ) ) ) ) .buildValidatorFactory(); 26
  27. New Constraints @NotEmpty, @NotBlank @Email @Positive, @PositiveOrZero , @Negative, @NegativeOrZero

    @PastOrPresent, @FutureOrPresent 27
  28. Other Java 8 Goodies Real parameter names in error messages

    ConstraintValidator without initialize() public class NotNullValidator implements ConstraintValidator<NotNull, Object> { public void initialize(NotNull constraintAnnotation) {} public boolean isValid(Object object, ConstraintValidatorContext ctx) { return object != null; } } public class NotNullValidator implements ConstraintValidator<NotNull, Object> { public boolean isValid(Object object, ConstraintValidatorContext ctx) { return object != null; } } 28
  29. Status Released final version in August Reference implementation: Hibernate Validator

    6.0 29
  30. Final Release Part of Java EE 8 Contained in GlassFish

    5; easy-to-use patch for WildFly Supported by Spring 5 Everything open source: spec, API, TCK and reference implementation 30
  31. Summary Support for container-element constraints Repeatable constraints New constraint types

    Improved date/time support ConstraintValidator#initialize() is a default method http://beanvalidation.org/2.0/spec/#whatsnew-20 31.1
  32. Outlook Bean Validation 2.1 Constraint-API ConstraintMapping mapping = ...; mapping.type(

    Marathon.class ) .property( "numberOfHelpers", FIELD ) .constraint( new MinDef().value( 1 ) ) .property( "runners", METHOD ) .valid(); 31.2
  33. Outlook Bean Validation 2.1 Constraint-API ConstraintMapping mapping = ...; mapping.type(

    Marathon.class ) .property( "numberOfHelpers", FIELD ) .constraint( new MinDef().value( 1 ) ) .property( "runners", METHOD ) .valid(); mapping.constraintDefinition( FileExists.class ) .validateType( File.class ) .with( f -> f.exists() ); Constraint-API: Lambda 31.3
  34. Resources Spec Reference implementation API, specifikation, TCK, website Contributions welcome!

    @gunnarmorling http://beanvalidation.org/2.0/spec/ github.com/hibernate/hibernate-validator/ github.com/beanvalidation/ 32
  35. 33