Validierungen sind ein wichtiger Bestandteil jeder Softwareentwicklung. Wir müssen überprüfen, ob die über die Benutzeroberfläche eingegebenen Daten korrekt sind, d.h. ob sie vom richtigen Typ sind oder ob wir ein notNull/notEmpty-Feld nicht leer lassen. Es gibt so viele Möglichkeiten, diese Anforderungen zu erfüllen, und wir können Validierungen auf UI-Ebene oder auf Persistenz-Ebene durchführen.
Schauen wir uns zunächst die Validierungen an, die wir haben können.
Hibernate Validierungen: Durch die Verwendung von Annotationen ist es sehr einfach, Validierungen auf eine Entität anzuwenden. Wir können z.B. die Annotation @NotNull verwenden, die im Grunde bedeutet, dass die Felder nicht Null sein dürfen. Wir können auch @Length verwenden und die minimale und maximale Länge für ein bestimmtes Feld angeben. Nehmen wir also an, wir haben eine Entität User, die wie folgt aussieht
@Entität
public class User {
private String userName;
private String passwordHash;
@NotEmpty
@Länge(min=1,max=5)
public String getUserName() {
return userName;
}
@NichtNull
public String getPasswordHash() {
return passwordHash;
}
....
}
Nachdem die Parameter der Entität User aktualisiert wurden und für die Persistenz bereit sind, wird die Hibernate-Validierung aufgerufen, um sicherzustellen, dass die Felder userName und passwordHash nicht null/leer sind oder dass die Länge des Feldes userName tatsächlich zwischen 1 und 5 liegt.
JSF-Validierungen: JSF bietet Validierungen auf UI-Ebene, die in der Prozessvalidierungsphase des JSF-Lebenszyklus durchgeführt werden. Sie werden durchgeführt, um sicherzustellen, dass die Daten gültig sind, bevor die Modelldaten aktualisiert werden, so dass wir uns beim Aufruf der Phase Invoke Application der Gültigkeit der Daten sicher sein können. Mit JSF können wir die gleichen Validierungen wie oben (d.h. für die Benutzerentität) auf der Benutzeroberfläche durchführen. Sehen wir uns den JSF-Code für das Feld userName an
Name: *
Die Angabe required="true" im Formular legt fest, dass die entsprechende Komponente einen Wert haben muss. JSF-Tag
Wie Seam diese Validierungen miteinander verknüpft
Seam führt Hibernate- und JSF-Validierungen zusammen, um jedes Datenfeld doppelt zu prüfen. Dies geschieht, indem zunächst UI-Validierungen (JSF) und dann annotationsbasierte Hibernate-Validierungen aufgerufen werden. Seam verwendet ModelValidator, um die Hibernate-Validierungen aufzurufen, nachdem die JSF-Validierungen erfolgreich ausgeführt wurden. Im Seam-Framework werden die Hibernate-Validierungen also zweimal angewendet. Erstens, wenn der Benutzer Daten eingibt und das Framework diese validiert und zweitens, wenn die erfolgreich validierten Daten persistiert werden.
Seam hat neue Tags <s:validate/> und <s:validateAll/> eingeführt, die den Hibernate Validator für die Eingabekomponente aufrufen. Damit wird eine Hibernate-Validator-JSF-Validator-Brücke registriert, die bei der Durchführung der Hibernate-Validierungen von der Benutzeroberfläche aus hilft, um dem Benutzer ein Feedback zu geben.
Hier macht Tag überflüssig, da es die Annotation der entsprechenden Modellklasseneigenschaft verwendet, um die Hibernate-Validierungen durchzuführen.
Ein merkwürdiges Verhalten
Obwohl Seam JSF- und Hibernate-Validierungen sehr gut integriert, gibt es ein etwas merkwürdiges Verhalten, auf das ich gestoßen bin, als ich untersucht habe, wie Validierungen in Seam funktionieren.
Die Angabe von @NotNull für das Modell beseitigt nicht die Anforderung, dass required="true" im JSF erscheinen muss. Dies ist auf eine Einschränkung der JSF-Validierungsarchitektur zurückzuführen. Wenn in einem JSF-Tag required="true" angegeben ist und in das Feld kein Wert eingegeben wird, werden die Hibernate-Validierungen nicht aktiviert, da das JSF-Framework zunächst den Wert des Feldes "required" untersucht. JSF aktiviert die Hibernate-Validierungen nur, wenn wir einen Wert eingeben. . Betrachten wir also ein Szenario mit 3 Bedingungen:
1. required="true" ist in JSF nicht angegeben
2. @NotNull-Anmerkung für das Feld in der Entität und @Length(max=4)
3. Es wurde kein Wert eingegeben und das Formular übermittelt.
In diesem Szenario aktiviert JSF keine Hibernate-Validierungen und ein leerer String wird an die Anwendung übergeben. Jetzt wird die zweite Ebene der Hibernate-Validierung aktiviert und da die @NotNull-Prüfung erfolgreich ist, da es sich um einen nicht leeren String handelt, wird das Feld in der Datenbank persistiert. Die @NotEmpty-Annotation ist ein guter Ersatz für @NotNull, wenn required="true" nicht angegeben ist. Wenn wir required = "true" in JSF mit der @NotNull-Annotation hinzufügen, werden die Hibernate-Validierungen umgangen und die Fehlermeldung "value is required" wird vom JSF-Framework zum Faces-Kontext hinzugefügt. Die Validierungen der zweiten Ebene werden beim Persistieren der Daten weiterhin durchgeführt.
AJAX-Validierungen: Seam bietet eine großartige AJAX-Unterstützung, die besonders für die Validierungen von Vorteil ist. In unserem vorherigen Beispiel wurden alle Validierungen beim Klicken auf die Schaltfläche Senden durchgeführt. Aber mit Ajax ist es möglich, eine sofortige Validierung zu erhalten, wenn Sie den Fokus auf das Eingabefeld verlieren. Ajax4jsf bietet ein Tag, mit dem Sie eine Ajax-Anfrage von der JSF-Seite aus senden können. Der Seam-JSF-Code mit Ajax-Unterstützung sieht dann so aus
Benutzername
Betrachten wir nun das gleiche Szenario wie oben, d.h.
1. required="true" ist in JSF nicht angegeben
2. @NotNull-Anmerkung für das Feld in der Entität und @Length(max=4)
3. Es wird kein Wert eingegeben und der Fokus wird aus dem Feld verschoben
Auch hier werden die Hibernate-Validierungen nicht von JSF aufgerufen. Auch die Hibernate-Validierungen der zweiten Ebene werden nicht durchgeführt, da das Formular noch nicht übermittelt wurde und daher keine Fehlermeldung angezeigt wird. Ähnlich verhält es sich, wenn required="true" zum JSF hinzugefügt wird: Das JSF-Framework prüft das required-Flag und fügt die Fehlermeldung zum Kontext hinzu.
Wir können auch benutzerdefinierte Validierungen mit Ajax durchführen. Nehmen wir ein einfaches Beispiel für die Registrierung eines Benutzers für Ihre Anwendung. Wir können ein Feld für den Benutzernamen, das Kennwort und das Bestätigungskennwort haben. Wir können ganz einfach per Ajax überprüfen, ob der in das Feld Passwort bestätigen eingegebene Wert mit dem im Feld Passwort übereinstimmt. Der JSF-Code für das Feld "Passwort bestätigen" sieht etwa so aus
Passwort Bestätigen
Hier ist registerAction eine Nahtkomponente und validatePassword ist die Methode, die nach dem Eintreten des Ereignisses "onblur" aufgerufen wird. Die Zeichenkette "passwordConfirm" wird an die registerAction übergeben und mit der vom Benutzer eingegebenen Zeichenkette "password" abgeglichen. Die entsprechende Nachricht wird zu den Faces-Nachrichten hinzugefügt. Da dieser Methodenaufruf über Ajax erfolgt, wird die Nachricht angezeigt, sobald der Fokus auf das Eingabefeld "Passowrd bestätigen" verschoben wird.
@Name("registerAction")
@Scope(ScopeType.CONVERSATION)
@Staatlich
@AutoCreate
public class RegisterAction implements Register {
@In(create = true)
Benutzer Benutzer;
@In(create = true)
UserHome userHome;
@In
private FacesMessages facesMessages;
private String passwordConfirm;
public boolean validatePassword() {
boolean validPassword = (user.getPasswordHash() != null && (user
.getPasswordHash().equals(passwordConfirm)));
if (!validPassword) {
facesMessages.addToControl("passwordConfirm",
"Passwörter stimmen nicht überein. Geben Sie Ihr Passwort erneut ein");
}
return validPassword;
}
.....
}
Der Zweck dieses Blogs war es, darüber zu sprechen, wie Validierungen in Seam durchgeführt werden, und auch über ein paar seltsame Szenarien, auf die ich bei meinen Recherchen zu diesem Thema gestoßen bin.
Verfasst von
Ruchika Goyal
Contact