JSR-303 Bean Validation API


                 •
                     Overview
                 •
                     Concept
                 •
                     Defining Constraints
                 •
                     Validate Constraints
                 •
                     Bootstrapping
                 •
                     Integration JEE/JSF


Heiko Scherrer
Preface JSR-303



  •
      Specifies common validation concept for
      JavaBeans™
  •
      For JavaEE & SE, extension of the
      JavaBeans object model
  •
      JSR-303 addresses validation in all
      layers of the application



Heiko Scherrer
Before JSR-303

                                                                          DDL: CHECK(length(email)==8)
   Script:if (email.length == 8) {...}




                                         if (email.length() == 8) {...}
                                                                          Person {
 <f:validateLength minimum="8" />                                         …
                                                                            @Column(length=8)
                                                                            String email;
                                                                          …
                                                                          }




Heiko Scherrer
Without Specification

  •
      Several validation frameworks exist:
       ●
           Apache Common-Validator
       ●
           Hibernate Validator
       ●
           JSF Validators
       ●
           ...
  •
      Not all frameworks for all layers
      =>Duplicated error-prone code
      =>Similar to JPA: A standard is needed!

Heiko Scherrer
With JSR-303




                                   Constraint is
                                   validated in
                                    all layers!

                 Person {
                 …
                   @Min(8)
                   String email;
                 …
                 }




Heiko Scherrer
JSR-303 - Concept



  •
      The JSR-303 API guarantees a stable,
      independent and extensible way to
      define constraints in domain objects and
      validate them
  •
      At least two implementations (SPI) are
      currently available: Hibernate, Spring3



Heiko Scherrer
JSR-303 - Concept
                             Specifies responsibilities
                             of the implementation: Validation.buildDefaultValidatorFactory()
                             Exceptions, Factories...




                                       Interesting parts
                                                           Validator definition:
                 Standard constraint                        Specifies how to
                     Definitions:                              validate data
                 @NotNull, @Min ...
                                                       validator.validate(myClass)




Heiko Scherrer
JSR-303 – Standard Constraints

Name             Description
@NotNull         must not be NULL
@AssertTrue      must not be true. NULL means valid
@AssertFalse     must not be false. NULL means valid
@Min             must be a number whose value must be higher or equal
@Max             must be a number whose value must be lower or equal
@DecimalMin      same as @Min
@DecimalMax      same as @Max
@Size            must been between the specified boundaries (included)
@Digits          must be a number within accepted range (included)
@Past            must be a date in the past
@Future          must be a date in the future
@Pattern         must match the defined regular expression




Heiko Scherrer
JSR-303 – Constraints

  •
      Constraints can be defined on methods, fields,
      annotations (constructors and parameters)
  •
      Custom constraints: @Constraint (see
      sourcecode example)
  •
      Constraints have properties: message,
      payload, groups
  •
      Annotated methods must follow the
      JavaBeans™ specification



Heiko Scherrer
JSR-303 – Constraints II


   •
       Validation of two separate properties is done
       within a validation method
   •
       A validation method is annotated with a
       Constraint and must follow JavaBeans Spec.

       @AssertTrue
       public boolean isValid() {
         …
         return qty1 > qty2;
       }


Heiko Scherrer
JSR-303 – Constraint example

    •
        Custom constraints can validate multiple fields
    •
        Some constraints apply to the database schema
    •
        Constraints can be grouped together using the groups
        property
    •
        The message text is interpolated ({…}) and
        internationalized
     Custom
    constraint


     Grouped
     together

     Simple
  constraint in
  default group

    Added a
  message text



Heiko Scherrer
JSR-303 – Grouping constraints

 •
      Not all declared constraints     Define a group:
                                       /**
      shall be validated each time      * A PersistenceGroup
                                        * validation group. This group
 •
      Different layers use perhaps a    * is validated in the integration layer.
                                        */
      different sequence of            public interface PersistenceGroup { }
      validation
 •
      Simple Java marker interfaces    In your domain class:
      (also classes) are used for      @NotNull(groups = PersistenceGroup.class)
                                       private String businessKey;
      grouping
 •
      Group inheritance with class     Validate the group:
      inheritance                      validator.validate(obj, PersistenceGroup.class);

 •
      Constraints on @Constraints      Bring all groups in a defined order:
      allows composing them            @GroupSequence(
                                       {Default.class, WMChecks.class,
                                                              PersistenceGroup.class})
 •
      Sequencing is done with          public interface SequencedChecks {
      @GroupSequence                   }




Heiko Scherrer
JSR-303 - Validation


 •
      Similar to JPA the Bean Validation API defines
      a factory to create a Validator
 •
      Validation is done with a Validator instance
 •
      Three methods at all:
      ●   validate(T object, Class<?>... groups)
      ●   validateProperty(T object,String pName, Class<?>... groups)
      ●   validateValue(Class<T> clazz, String pName, Object val, Class<?>... groups)

 •
      The return value is an empty Set in case the
      validation succeeds


Heiko Scherrer
JSR-303 – Validation (II)

           •
                 ConstraintViolation in case of failure
           •
                 to determine the reason why use methods like:
                 ●
                     String getMessage();
                 ●
                     Object getInvalidValue();
           •
                 ValidationMessages.properties file for custom messages
           •
                 @NotNull(message=”{org.openwms.resources.myText}”

Set<ConstraintViolation<MyClass>> c = validator.validate(obj);
assertEquals(1, c.size());


assertEquals("text defined with the constraint", c.iterator().next().getMessage());


assertEquals(2, validator.validate(obj, PersistenceGroup.class).size());


assertEquals(0, validator.validateProperty(obj, "qtyOnHand").size());


Heiko Scherrer
JSR-303 – Bootstrapping in J2SE

 •
     In a J2SE environment as well as JUnit test
     classes the factory/validator is instanciated:
       ●   ValidatorFactory f = Validation.buildDefaultValidatorFactory();
           Validator validator = factory.getValidator();

 •
     The ValidatorFactory is thread-safe,
     creation is an expensive operation
       ●
           This is done in a static method in the test super
           class
 •
     Creating the Validator is fast and can be
     done in each test execution method


Heiko Scherrer
JSR-303 – Bootstrapping in JEE6

  •
      In an EJB container it is not allowed to call the
      static build method
  •
      The factory and the validator are handled as
      Resources
  •
      In an EJB container use:
       ●   @Resource ValidatorFactory factory;
           @Resource Validator validator;

  •
      Or JNDI to lookup both:
       ●   initCtx.lookup("java:comp/ValidatorFactory");
           initCtx.lookup("java:comp/Validator");

  •
      JEE5 does not implement the Bean Val. SPI!

Heiko Scherrer
JSR-303 – Activation in JEE6/JPA

  •
      JPA2.0 comes along with built-in validation
      support with JSR-303
  •
      Persistence.xml defines a new element:
      <validation-mode>
        ●   AUTO:      Validation is done before create/update/delete
            if Validation provider is present
        ●   CALLBACK: An exception is raised when no Validator
            is present
        ●   NONE: Bean Validation is not used at all



Heiko Scherrer
JSR-303 – Usage in JSF2.0

 •
     Outside JEE6 use the servlet context param:
       ●   javax.faces.validator.beanValidator.ValidatorFactory
       ●
           Without this param the classpath is scanned
 •
     Within JEE6 use annotations or access the
     ServletContext. The container is responsible
     to make the factory available there
 •
     Validation can be done programatically or
     declarative
       ●
           <h:inputText value=”#{myBean.name}”>
               <f:validateBean />
           </h:inputText>



Heiko Scherrer
Recommended links




         •
             JSR-303 final specification
         •
             JSR-314 JSF2.0 final specification
         •
             JSR-316 JEE6 final specification
         •
             Hibernate Validator documentation




Heiko Scherrer
Q&A




Heiko Scherrer

JSR-303 Bean Validation API

  • 1.
    JSR-303 Bean ValidationAPI • Overview • Concept • Defining Constraints • Validate Constraints • Bootstrapping • Integration JEE/JSF Heiko Scherrer
  • 2.
    Preface JSR-303 • Specifies common validation concept for JavaBeans™ • For JavaEE & SE, extension of the JavaBeans object model • JSR-303 addresses validation in all layers of the application Heiko Scherrer
  • 3.
    Before JSR-303 DDL: CHECK(length(email)==8) Script:if (email.length == 8) {...} if (email.length() == 8) {...} Person { <f:validateLength minimum="8" /> … @Column(length=8) String email; … } Heiko Scherrer
  • 4.
    Without Specification • Several validation frameworks exist: ● Apache Common-Validator ● Hibernate Validator ● JSF Validators ● ... • Not all frameworks for all layers =>Duplicated error-prone code =>Similar to JPA: A standard is needed! Heiko Scherrer
  • 5.
    With JSR-303 Constraint is validated in all layers! Person { … @Min(8) String email; … } Heiko Scherrer
  • 6.
    JSR-303 - Concept • The JSR-303 API guarantees a stable, independent and extensible way to define constraints in domain objects and validate them • At least two implementations (SPI) are currently available: Hibernate, Spring3 Heiko Scherrer
  • 7.
    JSR-303 - Concept Specifies responsibilities of the implementation: Validation.buildDefaultValidatorFactory() Exceptions, Factories... Interesting parts Validator definition: Standard constraint Specifies how to Definitions: validate data @NotNull, @Min ... validator.validate(myClass) Heiko Scherrer
  • 8.
    JSR-303 – StandardConstraints Name Description @NotNull must not be NULL @AssertTrue must not be true. NULL means valid @AssertFalse must not be false. NULL means valid @Min must be a number whose value must be higher or equal @Max must be a number whose value must be lower or equal @DecimalMin same as @Min @DecimalMax same as @Max @Size must been between the specified boundaries (included) @Digits must be a number within accepted range (included) @Past must be a date in the past @Future must be a date in the future @Pattern must match the defined regular expression Heiko Scherrer
  • 9.
    JSR-303 – Constraints • Constraints can be defined on methods, fields, annotations (constructors and parameters) • Custom constraints: @Constraint (see sourcecode example) • Constraints have properties: message, payload, groups • Annotated methods must follow the JavaBeans™ specification Heiko Scherrer
  • 10.
    JSR-303 – ConstraintsII • Validation of two separate properties is done within a validation method • A validation method is annotated with a Constraint and must follow JavaBeans Spec. @AssertTrue public boolean isValid() { … return qty1 > qty2; } Heiko Scherrer
  • 11.
    JSR-303 – Constraintexample • Custom constraints can validate multiple fields • Some constraints apply to the database schema • Constraints can be grouped together using the groups property • The message text is interpolated ({…}) and internationalized Custom constraint Grouped together Simple constraint in default group Added a message text Heiko Scherrer
  • 12.
    JSR-303 – Groupingconstraints • Not all declared constraints Define a group: /** shall be validated each time * A PersistenceGroup * validation group. This group • Different layers use perhaps a * is validated in the integration layer. */ different sequence of public interface PersistenceGroup { } validation • Simple Java marker interfaces In your domain class: (also classes) are used for @NotNull(groups = PersistenceGroup.class) private String businessKey; grouping • Group inheritance with class Validate the group: inheritance validator.validate(obj, PersistenceGroup.class); • Constraints on @Constraints Bring all groups in a defined order: allows composing them @GroupSequence( {Default.class, WMChecks.class, PersistenceGroup.class}) • Sequencing is done with public interface SequencedChecks { @GroupSequence } Heiko Scherrer
  • 13.
    JSR-303 - Validation • Similar to JPA the Bean Validation API defines a factory to create a Validator • Validation is done with a Validator instance • Three methods at all: ● validate(T object, Class<?>... groups) ● validateProperty(T object,String pName, Class<?>... groups) ● validateValue(Class<T> clazz, String pName, Object val, Class<?>... groups) • The return value is an empty Set in case the validation succeeds Heiko Scherrer
  • 14.
    JSR-303 – Validation(II) • ConstraintViolation in case of failure • to determine the reason why use methods like: ● String getMessage(); ● Object getInvalidValue(); • ValidationMessages.properties file for custom messages • @NotNull(message=”{org.openwms.resources.myText}” Set<ConstraintViolation<MyClass>> c = validator.validate(obj); assertEquals(1, c.size()); assertEquals("text defined with the constraint", c.iterator().next().getMessage()); assertEquals(2, validator.validate(obj, PersistenceGroup.class).size()); assertEquals(0, validator.validateProperty(obj, "qtyOnHand").size()); Heiko Scherrer
  • 15.
    JSR-303 – Bootstrappingin J2SE • In a J2SE environment as well as JUnit test classes the factory/validator is instanciated: ● ValidatorFactory f = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); • The ValidatorFactory is thread-safe, creation is an expensive operation ● This is done in a static method in the test super class • Creating the Validator is fast and can be done in each test execution method Heiko Scherrer
  • 16.
    JSR-303 – Bootstrappingin JEE6 • In an EJB container it is not allowed to call the static build method • The factory and the validator are handled as Resources • In an EJB container use: ● @Resource ValidatorFactory factory; @Resource Validator validator; • Or JNDI to lookup both: ● initCtx.lookup("java:comp/ValidatorFactory"); initCtx.lookup("java:comp/Validator"); • JEE5 does not implement the Bean Val. SPI! Heiko Scherrer
  • 17.
    JSR-303 – Activationin JEE6/JPA • JPA2.0 comes along with built-in validation support with JSR-303 • Persistence.xml defines a new element: <validation-mode> ● AUTO: Validation is done before create/update/delete if Validation provider is present ● CALLBACK: An exception is raised when no Validator is present ● NONE: Bean Validation is not used at all Heiko Scherrer
  • 18.
    JSR-303 – Usagein JSF2.0 • Outside JEE6 use the servlet context param: ● javax.faces.validator.beanValidator.ValidatorFactory ● Without this param the classpath is scanned • Within JEE6 use annotations or access the ServletContext. The container is responsible to make the factory available there • Validation can be done programatically or declarative ● <h:inputText value=”#{myBean.name}”> <f:validateBean /> </h:inputText> Heiko Scherrer
  • 19.
    Recommended links • JSR-303 final specification • JSR-314 JSF2.0 final specification • JSR-316 JEE6 final specification • Hibernate Validator documentation Heiko Scherrer
  • 20.

Editor's Notes

  • #3 JSTL (JSP Standard Tag Library): extends JSP about useful tags JAX-RPC (Java API for XML Based RPC): CS communication with XML SAAJ (SOAP with Attachments API): Comparable with JMS, SOAP as transport protocol STAX (Streaming API for XML): Simplifies XML handling and eliminates SAX and DOM JSR-250 (Common annotations for the Java Platform): Aggregation of all Java EE and Java SE annotations JAF (JavaBeans Activation Framework): Typing, instantiation and reflection of unknown objects
  • #4 Not permitted (..): An enterprise bean must not use read/write static fields. Using read-only static fields is allowed An enterprise bean must not use the AWT functionality The enterprise bean must not attempt to use the Reflection API
  • #6 Not permitted (..): An enterprise bean must not use read/write static fields. Using read-only static fields is allowed An enterprise bean must not use the AWT functionality The enterprise bean must not attempt to use the Reflection API
  • #8 Not permitted (..): An enterprise bean must not use read/write static fields. Using read-only static fields is allowed An enterprise bean must not use the AWT functionality The enterprise bean must not attempt to use the Reflection API
  • #10 No annotation means Local interface Multiple Interceptors can be defined for a bean, the order is specified in the Core/Requ. Spec. Interceptors are stateless, but with the InvocationContext object it is possible to store data across method invocations @PostConstruct , @PreDestroy methods signature: any name, return void, throws no checked exceptions
  • #11 No annotation means Local interface Multiple Interceptors can be defined for a bean, the order is specified in the Core/Requ. Spec. Interceptors are stateless, but with the InvocationContext object it is possible to store data across method invocations @PostConstruct , @PreDestroy methods signature: any name, return void, throws no checked exceptions
  • #13 To redefine the Default group place @GroupSequence directly on the domain class
  • #14 The first method validates all constraints The second field validates a given field or property of an object The last one validates the property referenced by pName present on clazz or any of its superclasses, if the property value were val