„Drum prüfe, wer sich ewig bindet!“

Wie sich zeigt, wird die Validierung der Klassenattribute firstName und children auf die Gruppe HumanPerson beschränkt. Die referenzierte Klasse HumanPerson ist dabei lediglich ein Marker-Interface ohne Methoden. Stellt sich nur noch die Frage, wie die oben eingeführte Gruppenvalidierung aktiviert werden kann. Dies geschieht innerhalb der View:

Auch bei Verwendung des Bean-Validation-Ansatzes ist es relativ einfach möglich, eigene Validatoren zu implementieren, um sie anschließend zu verwenden. Zum einen muss eine Java-Klasse geschrieben werden, die das Interface javax.validation.ConstraintValidator und somit die beiden Methoden initialize(…)und validate(…)implementiert. Zum anderen benötigt es ein eigenes Tag, welches die eben beschriebene ConstraintValidator-Implementierung referenziert.

Ziel der Bean-Validation-Spezifikation ist es übrigens nicht, eine umfangreiche Sammlung an vorgefertigten Constraints zur Verfügung zu stellen. Die Ausrichtung der Spezifikation geht vielmehr dahin, eine solide Grundlage für die Implementierung eigener, wiederverwendbarer Validatoren zu liefern.

Missing Pieces

Alle bisher gezeigten Ansätze haben eines gemeinsam: Die Validierung bezieht sich auf einzelne Bean-Felder bzw. einzelne JSF-Eingabekomponenten. Zwar ist es dank Bean Validation möglich, Validierungen zu gruppieren, dies bedeutet aber lediglich, dass mehrere Einzelprüfungen bei Bedarf ein- bzw. ausgeschaltet werden können.

Wie aber lassen sich Validierungen realisieren, die sich über mehrere Eingabefelder erstrecken? Ein Beispiel hiefür wäre die Eingabe eines Passworts sowie einer dazu passenden Passwortwiederholung. Spätestens für diesen Validierungsfall sind wir aktuell leider gezwungen, auf eine 3rd-Party-JSF-Validierungsbibliothek zurück zu greifen, wenn wir uns nicht unnötig viel Arbeit machen möchten.

Ein guter Kandidat ist hier die bereits oben erwähnte Open-Source-Bibliothek Apache MyFaces External Validation, die sowohl für JSF 1.1 und 1.2 als auch für 2.0 zur Verfügung steht.

Mithilfe von extVal lässt sich das Problem der Cross Validation einfach lösen. Listing 3 zeigt das bereits bekannte Beispiel in leicht abgeänderter Form, ergänzt um ein Cross-Validation-Feature.

Listing 3: Cross Validation mit extVal
public class Person {
   
   @Required
   @NotEquals("lastName")
   private String firstName; 
   
   @Required
   private String name; 
   ...
}

Die Möglichkeiten der extVal Cross Validation gehen dabei deutlich weiter, als dies an einem kleinen Beispiel gezeigt werden kann. So können neben den skizzierten Cross-Checks innerhalb einer Klasse, auch instanzübergreifende Validierungen stattfinden oder aber es kann mittels @JoinValidation auf Validierungsregeln innerhalb einer anderen Klasse verwiesen werden, anstatt diese ein zweites Mal redundant angeben zu müssen.

Ein weiteres Feature ist das „Skippen“ von Validierungen unter bestimmten Bedingungen via @SkipValidation. Ein denkbares Szenario wäre das Überspringen von Validierungen für den Fall, dass der im Hintergrund angemeldete User – in unserem Fall repräsentiert durch eine ManagedBean namens loggedInUser – die Rolle des admin inne hat: @SkipValidation(„#{loggedInUser.roles eq ‚admin‘}“).

Neben der Unterstützung des oben beschriebenen Bean Validation JSR 303 ist extVal auch in der Lage, eine Validierung auf Basis von JPA-Annotationen durchzuführen. Dies entspricht dem DRY Pattern („Don’t Repeat Yourself“) und vermeidet redundante Prüfregeln, kann gleichzeitig aber auch zu sehr „overloaded“ Entities führen. Auch ein Mix von beiden – zum Beispiel Bean Validation innerhalb einer ManagedBean und JPA Validation innerhalb einer Entität – wird von extVal unterstütz und sorgt in beiden Fällen für entsprechende bei Bedarf internationalisierte JSF-Fehlermeldungen für den Nutzer.

Fazit

Es zeigt sich, dass die JSF-Spezifikation noch einige Lücken beim Thema Validierung aufweist. Einfache Fälle können problemlos abgehandelt werden, und dank Bean Validation ist der JSF-Entwickler auch nicht mehr gezwungen, die Validierung direkt in der View zu platzieren. Aber bereits bei dem Thema der Cross Field Validation stößt die aktuelle Spezifikation an ihre Grenzen. Noch komplizierter wird es, wenn über Komponenten- oder Entitäten-Grenzen hinweg validiert werden soll. Spätestens dann ist der JSF-Entwickler auf eine 3rd-Party-Lösung angewiesen. Der eine oder andere Leser wird sich fragen, wie es denn im JSF-Umfeld um Client Side Validation steht. Dies ist ein anderes, fast schon philosophischem Thema- eventuell für eine eigene Kolumne…

Lars Röwekamp ist Geschäftsführer der OpenKnowledge GmbH und berät seit mehr als zehn Jahren Kunden in internationalen Projekten rund um das Thema Enterprise Computing (Twitter: @mobileLarson).

Matthias Weßendorf arbeitet für die Firma Kaazing. Dort beschäftigt er sich mit WebSocket, HTML5 und weiteren Themen rund um das „Next Generation Web“. Matthias blogt regelmäßig auf http://matthiaswessendorf.wordpress.com.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.