• Save
Objektvalidierung mit dem Bean Validation Api
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Objektvalidierung mit dem Bean Validation Api

  • 13,156 views
Uploaded on

Slides meines Vortrags zum Bean Validation API (JSR 303) bei der JUG Hamburg

Slides meines Vortrags zum Bean Validation API (JSR 303) bei der JUG Hamburg

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
13,156
On Slideshare
11,532
From Embeds
1,624
Number of Embeds
39

Actions

Shares
Downloads
0
Comments
0
Likes
2

Embeds 1,624

http://musingsofaprogrammingaddict.blogspot.com 1,024
http://musingsofaprogrammingaddict.blogspot.de 109
http://musingsofaprogrammingaddict.blogspot.in 80
http://musingsofaprogrammingaddict.blogspot.com.es 73
http://musingsofaprogrammingaddict.blogspot.com.br 42
http://musingsofaprogrammingaddict.blogspot.co.uk 36
http://feeds.feedburner.com 26
http://musingsofaprogrammingaddict.blogspot.fr 22
http://musingsofaprogrammingaddict.blogspot.it 17
http://musingsofaprogrammingaddict.blogspot.com.ar 16
http://musingsofaprogrammingaddict.blogspot.ch 14
http://musingsofaprogrammingaddict.blogspot.se 13
http://www.slideshare.net 13
http://musingsofaprogrammingaddict.blogspot.co.il 12
http://musingsofaprogrammingaddict.blogspot.fi 12
http://musingsofaprogrammingaddict.blogspot.hk 12
http://musingsofaprogrammingaddict.blogspot.co.at 11
http://musingsofaprogrammingaddict.blogspot.mx 11
http://musingsofaprogrammingaddict.blogspot.ca 10
http://musingsofaprogrammingaddict.blogspot.com.au 9
http://musingsofaprogrammingaddict.blogspot.be 9
http://musingsofaprogrammingaddict.blogspot.hu 9
http://musingsofaprogrammingaddict.blogspot.cz 7
http://musingsofaprogrammingaddict.blogspot.ru 5
http://musingsofaprogrammingaddict.blogspot.kr 4
http://musingsofaprogrammingaddict.blogspot.no 3
http://musingsofaprogrammingaddict.blogspot.ro 3
http://musingsofaprogrammingaddict.blogspot.pt 3
http://musingsofaprogrammingaddict.blogspot.nl 3
http://musingsofaprogrammingaddict.blogspot.sk 3
http://musingsofaprogrammingaddict.blogspot.co.nz 2
http://musingsofaprogrammingaddict.blogspot.sg 2
http://musingsofaprogrammingaddict.blogspot.tw 2
http://musingsofaprogrammingaddict.blogspot.jp 2
http://musingsofaprogrammingaddict.blogspot.com.tr 1
http://webcache.googleusercontent.com 1
http://theoldreader.com 1
http://translate.googleusercontent.com 1
http://musingsofaprogrammingaddict.blogspot.ie 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Objektvalidierung mit dem Bean Validation API JUG Hamburg – 07.04.2010 Gunnar Morling
  • 2. Gunnar Morling • Contributor bei Hibernate Validator • Blogger (http://www.gunnarmorling.de/) • Softwarearchitekt/Entwicklungsleiter bei der Otto Group 07.04.2010 Bean Validation API 2/29
  • 3. Validierung allerorten • String: – nicht null – gültige E-Mail-Adresse oder URL – gültige PLZ • Zahl: – zwischen 0 und 100 – gültige Kreditkartennummer • GUI: Passwort_1 = Passwort_2 • Rechungsdatum nicht null (aber nur dann, wenn Auftrag im Zustand “fakturiert”) 07.04.2010 Bean Validation API 3/29
  • 4. Das Problem... • Redundante Definition von Constraints • Mögliche Inkonsistenzen • Verschiedene Runtimes, verschiedene Validatoren 07.04.2010 Bean Validation API 4/29
  • 5. ... und die Lösung • Constraints an zentraler Stelle, eine Runtime • Realisierungsmöglichkeiten: programmatisch vs. deklarativ • Quelle für Constraints in angrenzende Systemen (JavaScript, DDL) 07.04.2010 Bean Validation API 5/29
  • 6. “Hello, Bean Validation!” public class Car {     @NotNull     private String manufacturer;     @NotNull     @Size(min = 2, max = 14)     private String licensePlate;     @Min(value=2, message="Seat count must be 2 at least.")     private int seatCount;          public Car(String manufacturer, String licencePlate, int seatCount) {         //...     }     //... } • Constraints: Annotationen mit Standard- (u.a. “message”) und spezifischen (z.B. “min”, “max”) Attributen 07.04.2010 Bean Validation API 6/29
  • 7. JSR 303: “Bean Validation” • JSR 303: – Metamodell: Wie werden Constraints ausgedrückt? – API: Wie werden Constraints ausgewertet? • Spec Lead: Emmanuel Bernard (RedHat) • In allen Anwendungsschichten nutzbar • Teil von Java EE 6, aber auch unter SE nutzbar • Implementierungen: – Hibernate Validator (Referenzimplementierung, Teil von GF v3) – Agimatec Validation – Weitere geplant (z.B. OVal) 07.04.2010 Bean Validation API 7/29
  • 8. Demo 1: Constraints definieren • Demo 1: – Felder – Properties – Vererbung 07.04.2010 Bean Validation API 8/29
  • 9. Validierung von Objektgraphen public class Person {     @NotNull     @Size(min=3, max=50)     private String name;     //... } public class Car {     private String manufacturer;     private String licensePlate;     private int seatCount;          @NotNull     private Person driver;     //... } 07.04.2010 Bean Validation API 9/29
  • 10. Validierung von Objektgraphen public class Person {     @NotNull     @Size(min=3, max=50)     private String name;     //... } public class Car {     private String manufacturer;     private String licensePlate;     private int seatCount;          @NotNull     @Valid     private Person driver;     //... } 07.04.2010 Bean Validation API 9/29
  • 11. Feldübergreifende Validierung • Validierung mitunter von mehreren Attributen einer Klasse abhängig: public class Car {     private String manufacturer;     private String licensePlate;     @Min(value=2)     private int seatCount;          @NotNull     @NotEmpty     private List<Person> passengers;     //... } 07.04.2010 Bean Validation API 10/29
  • 12. Feldübergreifende Validierung • Mittels Class-Level-Constraints Zugriff auf alle Attribute einer Klasse möglich: @PassengerCount public class Car {     private String manufacturer;     private String licensePlate;     @Min(value=2)     private int seatCount;          @NotNull     @NotEmpty     private List<Person> passengers;     //... } 07.04.2010 Bean Validation API 10/29
  • 13. Vordefinierte Constraints • Bestandteil von JSR 303 – @Null, @NotNull – @AssertFalse, @AssertTrue – @Past, @Future – @Min, @Max, @Digits, @DecimalMin, @DecimalMax – @Size, @Pattern – @Valid • Zusätzlich in Hibernate Validator 4.0 – @Email – @Length – @NotEmpty – @Range 07.04.2010 Bean Validation API 11/29
  • 14. Constraints auswerten • javax.validation.Validator: Car car = new Car(null, "DD­AB­123", 4);      Validator validator =      Validation.buildDefaultValidatorFactory().getValidator(); //Objekt validieren Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car);      //Property validieren constraintViolations = validator.validateProperty(car, "licensePlate");      //Wert validieren constraintViolations =      validator.validateValue(Car.class, "licensePlate", "DD­AB­123"); 07.04.2010 Bean Validation API 12/29
  • 15. javax.validation.ConstraintViolation Car car = new Car("Morris", "DD­AB­123", 1); Validator validator =  Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); ConstraintViolation<Car> violation = constraintViolations.iterator().next(); assertEquals(car, violation.getRootBean()); assertEquals("seatCount",      violation.getPropertyPath().iterator().next().getName()); assertEquals(1, violation.getInvalidValue()); assertEquals("Seat count must be 2 at least.", violation.getMessage()); assertEquals(Min.class,     violation.getConstraintDescriptor().getAnnotation().annotationType()); 07.04.2010 Bean Validation API 13/29
  • 16. Validierungsgruppen • Erfordernis, nur Teilmengen der Constraints zu prüfen: – Objektlebenszyklus – Wizards – Nutzerrolle • Repräsentation in Form von Interfaces (Vererbungsbe- ziehungen, typsicher): •    public interface MyValidationGroup {} • Zuordnung von Constraints zu Gruppen: – Parameter “groups” – Ohne Zuordnung: javax.validation.groups.Default 07.04.2010 Bean Validation API 14/29
  • 17. Validierungsgruppen – Beispiel public class Order {     @NotNull @Size(min = 10, max = 10)     @Pattern(regexp = "ON[0­9]*")     private String orderNumber;     @Valid @NotNull @Size(min = 1, max = 50)     private List<OrderLine> orderLines;     @NotNull @Past     private Date orderDate;     @NotNull @Past     private Date invoiceDate;     // ... } 07.04.2010 Bean Validation API 15/29
  • 18. Validierungsgruppen – Beispiel public class Order {     public interface AfterProcessing {}     @NotNull @Size(min = 10, max = 10) @Pattern(regexp = "ON[0­9]*")     private String orderNumber;     @Valid @NotNull @Size(min = 1, max = 50)     private List<OrderLine> orderLines;     @NotNull @Past     private Date orderDate;     @NotNull(groups=AfterProcessing.class) @Past(groups=AfterProcessing.class)     private Date invoiceDate;          // ... } Validator validator = ...; Order order = ...; validator.validate(order, AfterProcessing.class); 07.04.2010 Bean Validation API 15/29
  • 19. @GroupSequence • Festlegung von Ausführungsreihenfolgen: – Prüfung sehr teuer (CPU, externe Services etc.) – Prüfung von Constraints erfordert validen Basiszustand @GroupSequence({Default.class, AfterProcessing.class}) public interface Complete {} • • Festlegung der Default-Gruppe: @GroupSequence({Order.class, AfterProcessing.class}) public class Order {     // ... } 07.04.2010 Bean Validation API 16/29
  • 20. Eigene Constraints definieren • Die Standard-Constraints können um eigene erweitert werden, z.B.: – Gültige Postleitzahl – Quersumme einer Auftragsnummer mod 10 = 0 – Event.startDate < Event.endDate • Was wird benötigt: – Constraint-Annotation – Validator(en) – Fehlertext ➔ Demo 2 07.04.2010 Bean Validation API 17/29
  • 21. Zusammengesetzte Constraints • Drei Constraints für Validierung des Nummernschilds • Andere Entitäten mit gleichem Attribut? @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) private String licensePlate; 07.04.2010 Bean Validation API 18/29
  • 22. Zusammengesetzte Constraints @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) private String licensePlate; @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) @Constraint(validatedBy={}) @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidLicensePlate {     String message() default "{de.jughh.bv.ValidLicensePlate.message}";     Class<?>[] groups() default {};     Class<? extends Payload>[] payload() default {}; } 07.04.2010 Bean Validation API 19/29
  • 23. Zusammengesetzte Constraints @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) private String licensePlate; @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) @Constraint(validatedBy={}) @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidLicensePlate {     String message() default "{de.jughh.bv.ValidLicensePlate.message}";     Class<?>[] groups() default {};     Class<? extends Payload>[] payload() default {}; } @ValidLicensePlate private String licensePlate; 07.04.2010 Bean Validation API 19/29
  • 24. Zusammengesetzte Constraints • Rückgabe einer einzigen Constraint-Verletzung per @ReportAsSingleViolation: @NotNull @Size(min = 2, max = 14) @CheckCase(CaseMode.UPPER) @ReportAsSingleViolation @Constraint(validatedBy={}) @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidLicensePlate {     String message() default "{de.jughh.bv.ValidLicensePlate.message}";     Class<?>[] groups() default {};     Class<? extends Payload>[] payload() default {}; } 07.04.2010 Bean Validation API 20/29
  • 25. XML-Konfiguration: validation.xml <?xml version="1.0" encoding="UTF­8"?> <validation­config   xmlns="http://jboss.org/xml/ns/javax/validation/configuration"   xmlns:xsi="http://www.w3.org/2001/XMLSchema­instance"   xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration                                            validation­configuration­1.0.xsd">          <constraint­validator­factory>       de.jughh.bv.MyConstraintValidatorFactory     </constraint­validator­factory>     <message­interpolator>       de.jughh.bv.MyMessageInterpolator     </message­interpolator>     <constraint­mapping>       META­INF/validation/car­constraints.xml     </constraint­mapping>     <constraint­mapping>...</constraint­mapping>     <property name="de.jughh.bv.validation.logging">WARN</property> </validation­config> 07.04.2010 Bean Validation API 21/29
  • 26. XML-Konfiguration: Constraint-Mappings <?xml version="1.0" encoding="UTF­8"?> <constraint­mappings    xmlns="http://jboss.org/xml/ns/javax/validation/mapping"   xmlns:xsi="http://www.w3.org/2001/XMLSchema­instance"   xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping                                                 validation­mapping­1.0.xsd">   <default­package>de.jughh.bv.domain</default­package>   <bean class="Car" ignore­annotations="false">     <field name="licensePlate">       <constraint annotation="javax.validation.constraint.Size">         <message>Size of license plate is limited</message>         <groups>           <value>de.jughh.bv.LightValidation</value>         </groups>         <element name="max">10</element>       </constraint>     </field>   </bean> </constraint­mappings> 07.04.2010 Bean Validation API 22/29
  • 27. Bootstrapping //1. Default­Factory Validator validator =      Validation.buildDefaultValidatorFactory().getValidator(); //2. Angepasste Factory Configuration<?> configuration = Validation.byDefaultProvider().configure();      ValidatorFactory validatorFactory = configuration     .messageInterpolator(         new MyMessageInterpolator(             configuration.getDefaultMessageInterpolator()))     .constraintValidatorFactory(         new MyConstraintValidatorFactory(             configuration.getDefaultConstraintValidatorFactory()))     .ignoreXmlConfiguration()     .buildValidatorFactory();      Validator validator = validatorFactory.getValidator(); //3. Providerspezifische Konfiguration HibernateValidatorConfiguration configuration =      Validation.byProvider(HibernateValidator.class).configure(); 07.04.2010 Bean Validation API 23/29
  • 28. Integration mit anderen APIs • JPA 2 – Validierung vor Insert, Update (& Delete) – Kein Nachladen aus der DB – Berücksichtigung von Constraints für DDL • JSF 2 – Autom. Validierung aller gebundenen Properties – Wichtig: javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = true • Java EE 6 – Injektion von ValidatorFactory und Validator:     @Resource     private ValidatorFactory validatorFactory;     @Resource     private Validator validator; 07.04.2010 Bean Validation API 24/29
  • 29. 07.04.2010 Bean Validation API /29
  • 30. Neues in Hibernate Validator 4.1 • Annotation Processor: Constraintprüfung zur Compile-Zeit • Neue Constraints – @CreditCardNumber – @NotBlank – @URL – @ScriptAssert: • @ScriptAssert(lang = "jexl", script = "_this.startDate < _this.endDate") public class CalendarEvent { •     private Date startDate; •     private Date endDate; •     //constructor, getter, setter ... } RBL • 07.04.2010 Bean Validation API 26/29
  • 31. 07.04.2010 Bean Validation API /29
  • 32. Fragen & Antworten ?! 07.04.2010 Bean Validation API 28/29
  • 33. Referenzen • JSR 303: “Bean Validation”: http://jcp.org/en/jsr/detail?id=303 • Hibernate Validator 4.0: http://www.hibernate.org/subprojects/validator.html • Hibernate Validator Reference Guide: http://docs.jboss.org/hibernate/stable/validator/reference/ en/html/ • Forum zu Hibernate Validator: https://forum.hibernate.org/viewforum.php?f=9 • Musings of a programming Addict – Artikel zu BV: http://musingsofaprogrammingaddict.blogspot.com/search/ label/Bean%20Validation 07.04.2010 Bean Validation API 29/29