This document discusses JSR-303, which specifies a common validation concept for JavaBeans. It defines constraints that can be used to validate objects in all layers of an application. Some key points covered include defining constraints using annotations, validating objects against those constraints, and integrating validation into Java EE and JSF. The JSR-303 API provides a standardized way to define and validate constraints across frameworks and layers.
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 – 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
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 – 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
11. 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
12. 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
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 – 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
16. 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
17. 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
18. 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
19. Recommended links
•
JSR-303 final specification
•
JSR-314 JSF2.0 final specification
•
JSR-316 JEE6 final specification
•
Hibernate Validator documentation
Heiko Scherrer
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
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
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
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
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
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
To redefine the Default group place @GroupSequence directly on the domain class
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