Author: hardy.ferentschik
Date: 2009-03-30 06:45:18 -0400 (Mon, 30 Mar 2009)
New Revision: 16227
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
Log:
latest doc changes
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml 2009-03-27
17:12:01 UTC (rev 16226)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml 2009-03-30
10:45:18 UTC (rev 16227)
@@ -314,7 +314,7 @@
assertEquals(1, constraintViolations.size());
assertEquals(
"Case mode must be UPPER.",
- constraintViolations.iterator().next().getInterpolatedMessage());
+ constraintViolations.iterator().next().getMessage());
}
@Test
@@ -552,7 +552,7 @@
assertEquals(1, constraintViolations.size());
assertEquals(
"Passenger count must be less than or equal to seat count.",
- constraintViolations.iterator().next().getInterpolatedMessage());
+ constraintViolations.iterator().next().getMessage());
}
@Test
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2009-03-27
17:12:01 UTC (rev 16226)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2009-03-30
10:45:18 UTC (rev 16227)
@@ -25,33 +25,409 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="validator-usingvalidator">
- <title>Using the Validator API</title>
+ <title>Object validation using the Bean Validation API</title>
+ <para>TODO: outline of the chapter. Should this be placed before <link
+ lang="" linkend="validator-customconstraints">"Creating
custom
+ constraints"</link>?</para>
+
<section id="validator-usingvalidator-annotate"
revision="1">
- <title>Annotate your model</title>
+ <title>Annotating your model</title>
- <para>Field, Getter</para>
+ <para>Using the Bean Validation API validation constraints are expressed
+ via Java 5 annotations. In this section it will be shown how to annotate
+ your object model with Bean Validation constraint annotations.</para>
+
+ <section>
+ <title>Field validation</title>
+
+ <para>One way for expressing constraints is to annotate the fields of a
+ class with constraint annotations. The following listing shows a simple
+ example:</para>
+
+ <programlisting>package com.mycompany;
+
+import javax.validation.constraints.NotNull;
+
+public class Car {
+
+ @NotNull
+ private String manufacturer;
+
+ public Car(String manufacturer) {
+
+ this.manufacturer = manufacturer;
+ }
+
+}</programlisting>
+ </section>
+
+ <section>
+ <title>Property validation</title>
+
+ <para>If your model class adheres to the <ulink type=""
+
url="http://java.sun.com/javase/technologies/desktop/javabeans/index...
+ standard (meaning basically, there are getter and setter methods for the
+ properties of the class), it is also possible to annotate the properties
+ of a bean class instead of its fields. Note that the property's getter
+ method has to be annotated, not its setter method:</para>
+
+ <programlisting>package com.mycompany;
+
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotNull;
+
+public class Car {
+
+ private String manufacturer;
+
+ private boolean isRegistered;
+
+
+ public Car(String manufacturer, boolean isRegistered) {
+ super();
+ this.manufacturer = manufacturer;
+ this.isRegistered = isRegistered;
+ }
+
+ @NotNull
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public void setManufacturer(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+ @AssertTrue
+ public boolean isRegistered() {
+ return isRegistered;
+ }
+
+ public void setRegistered(boolean isRegistered) {
+ this.isRegistered = isRegistered;
+ }
+
+}</programlisting>
+
+ <para>Generally it is considered a good practice to stick either with
+ field OR with property annotation within one model class for the sake of
+ readability. It is not recommended to annotate a field AND the
+ accompanying getter method as this would cause the field to be validated
+ twice.</para>
+ </section>
+
+ <section>
+ <title>Class-level annotations</title>
+
+ <para>TODO: Should this be mentioned here?</para>
+ </section>
+
+ <section>
+ <title>Annotated interfaces and super-classes</title>
+
+ <para>When validating an object that implements some interface or
+ extends another class, all constraint annotations at the properties of
+ that interface or parent class apply in the same manner as the
+ constraint annotations at the validated object itself. To make things
+ clearer let's have a look at the following example:</para>
+
+ <programlisting>//class Car
+package com.mycompany;
+
+import javax.validation.constraints.NotNull;
+
+public class Car {
+
+ private String manufacturer;
+
+ public Car(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+ @NotNull
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public void setManufacturer(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+}
+
+//class RentalCar
+package com.mycompany;
+
+import javax.validation.constraints.NotNull;
+
+public class RentalCar extends Car {
+
+ private String rentalStation;
+
+ public RentalCar(String manufacturer, String rentalStation) {
+ super(manufacturer);
+ this.rentalStation = rentalStation;
+ }
+
+ @NotNull
+ public String getRentalStation() {
+ return rentalStation;
+ }
+
+ public void setRentalStation(String rentalStation) {
+ this.rentalStation = rentalStation;
+ }
+
+}</programlisting>
+
+ <para>Our well-known class Car is now extended by RentalCar with an
+ additional property, rentalStation. If an instance of RentalCar is
+ validated now, not only the @NotNull constraint at the rentalStation
+ property would be validated, but also the constraint at manufacturer
+ from the parent class.</para>
+
+ <para>The same would hold true, if Car was an interface, that is
+ implemented by RentalCar.</para>
+
+ <para>Constraint annotations are aggregated if methods are overridden.
+ If RentalCar would override the getManufacturer() method from Car any
+ constraints annotated at the overriding method would be evaluated in
+ addition to the @NotNull constraint from the super-class.</para>
+ </section>
+
+ <section>
+ <title>Validating object graphes</title>
+
+ <para>The Bean Validation API does not only allow to validate single
+ objects but also complete object graphs. To do so just annotate a field
+ or property representing a reference to another object with
+ @Valid.</para>
+
+ <para>If the parent object is validated, all objects referenced by a
+ field/property annotated with @Valid will be validated as well (as will
+ be their children etc.). The following shows a simple example:</para>
+
+ <programlisting>//class Person
+package com.mycompany;
+
+import javax.validation.constraints.NotNull;
+
+public class Person {
+
+ @NotNull
+ private String name;
+
+ public Person(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
+
+//class car
+package com.mycompany;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+public class Car {
+
+ @NotNull
+ @Valid
+ private Person driver;
+
+ public Car(Person driver) {
+
+ this.driver = driver;
+ }
+
+ //getters and setters ...
+
+}</programlisting>
+
+ <para>If an instance of Car is validated, the referenced Person object
+ will be validated as well, as the driver field is annotated with @Valid.
+ Therefore the validation of a Car will fail if the name field of the
+ referenced Person instance is null.</para>
+
+ <para>Object graph validation also works for collection-typed fields.
+ That means any attributes that are</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>arrays</para>
+ </listitem>
+
+ <listitem>
+ <para>of type java.lang.Iterable (and therfore its direct or
+ indirect derivations Collection, List and Set)</para>
+ </listitem>
+
+ <listitem>
+ <para>of type java.util.Map</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>can be annotated with @Valid, which will cause each contained
+ element to be validated, when the parent object is validated.</para>
+
+ <programlisting>package com.mycompany;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import org.hibernate.validation.constraints.NotEmpty;
+
+public class Car {
+
+ @NotNull
+ @Valid
+ private List<Person> passengers = new
ArrayList<Person>();
+
+ public Car(List<Person> passengers) {
+
+ this.passengers = passengers;
+ }
+
+ //getters and setters ...
+
+}</programlisting>
+
+ <para>If a Car instance is validated now, a ConstraintValidation will be
+ raised, if any of the Person objects contained in the passenger list has
+ a null name.</para>
+ </section>
</section>
<section id="validator-usingvalidator-validate"
revision="1">
- <title>Object validation</title>
+ <title>Using the Validator API</title>
- <para>Plain, Use of @Valid</para>
+ <para>The Validator interface is the main entry point to the Bean
+ Validation API. In the following we first will show how to obtain
+ Validator instances using the bootstrapping mechanism that the API
+ provides. Afterwards you'll learn how to use the different methods of the
+ Validator interfaces followed by an overview of the information that
+ ConstraintViolation instances offer.</para>
+
+ <section>
+ <title>Obtaining Validator instances</title>
+
+ <para>TODO: DefaultFactory, customization, note on thread
safety</para>
+ </section>
+
+ <section>
+ <title>Validator methods</title>
+
+ <para>The Validator interface contains three methods that can be used to
+ validate entire objects or only single object properties. </para>
+
+ <para>All of these methods return a Set<ConstraintViolation>,
+ which will be empty, if the validation succeeded. Otherwise a
+ ConstraintViolation object for each violated constraint will be
+ contained.</para>
+
+ <para>All the validation methods have a var-args parameter which can be
+ used to specify, which validation groups shall be considered when
+ performing the validation. If the parameter is not specified (as in the
+ following examples) the default validation group will be used. We will
+ go into more detail on the topic of validation groups in the <link
+ linkend="validator-usingvalidator-validationgroups">following
+ section</link>.</para>
+
+ <section>
+ <title>validate()</title>
+
+ <para>Use the validate() method to perform validation of all
+ constraints of a given object. The following listing shows an
+ example:</para>
+
+ <programlisting>ValidatorFactory factory =
Validation.buildDefaultValidatorFactory();
+Validator validator = factory.getValidator();
+
+Car car = new Car(null);
+
+Set<ConstraintViolation<Car>> constraintViolations =
+ validator.validate(car);
+
+assertEquals(1, constraintViolations.size());
+assertEquals(
+ "may not be null",
constraintViolations.iterator().next().getMessage());</programlisting>
+ </section>
+
+ <section>
+ <title>validateProperty()</title>
+
+ <para>With help of the validateProperty() a single named property of a
+ given object can be validated:</para>
+
+ <programlisting>Validator validator =
Validation.buildDefaultValidatorFactory().getValidator();
+
+Car car = new Car(null);
+
+Set<ConstraintViolation<Car>> constraintViolations =
+ validator.validateProperty(car, "manufacturer");
+
+assertEquals(1, constraintViolations.size());
+assertEquals(
+ "may not be null",
constraintViolations.iterator().next().getMessage());</programlisting>
+ </section>
+
+ <section>
+ <title>validateValue()</title>
+
+ <para>Using the validateValue() method you can check, whether a single
+ property of a given class can be validated successfully, if the
+ property had the specified value:</para>
+
+ <programlisting>Validator validator =
Validation.buildDefaultValidatorFactory().getValidator();
+
+Set<ConstraintViolation<Car>> constraintViolations =
+ validator.validateValue(Car.class, "manufacturer", null);
+
+assertEquals(1, constraintViolations.size());
+assertEquals(
+ "may not be null",
constraintViolations.iterator().next().getMessage());</programlisting>
+ </section>
+
+ <section>
+ <title>getConstraintsForClass()</title>
+
+ <para>TODO: Should this be mentioned here?</para>
+ </section>
+ </section>
+
+ <section>
+ <title>Working with ConstraintViolations</title>
+
+ <para>TODO: Message interpolation?</para>
+ </section>
</section>
<section id="validator-usingvalidator-validationgroups"
revision="1">
<title>Validation groups</title>
- <para><section revision="1">
- <title>Group sequences</title>
+ <section revision="1">
+ <title>Group sequences</title>
- <para />
- </section></para>
+ <para></para>
+ </section>
</section>
<section id="validator-usingvalidator-methodparameters"
revision="1">
- <title>Validating method parameters</title>
-
- <para></para>
+ <para />
</section>
</chapter>