Eine Standardaufgabe innerhalb einer Applikation ist die Überprüfung von Benutzereingaben. Immer wieder muss dafür ähnlicher Programmode eingesetzt werden. Deshalb bietet JSF hier ein Konzept, dass die Validierung von Benutzereingaben auf einfache Weise ermöglicht. 

Die Gültigkeitsprüfungen einer JSF-Applikation sind Teil des standardmäßigen Abarbeitungszyklus' eines Requests. Sie werden in der Process Validation Phase durchgeführt. Zu diesem Zeitpunkt sind die Eingabewerte bereits aus dem HTTP-Request in den View-Baum übertragen.

Die Vorbereitung: Fehlermeldungen anzeigen

Um dem Benutzer eine Meldung anzeigen zu können, wenn beim Validieren Eingabefehler erkannt werden, kann der Seitenautor sich bei der Entwicklung einer Facelet-View-Definition eines der folgenden Elemente bedienen, die ihm von der JSF HTML-Bibliothek zur Verfügung gestellt werden:

<h:message for="element-id" />
<h:message />

Während das erste Element Meldungen für ein einzelnes Eingabeelement anzeigt, liefert das zweite Element Meldungen für verschiedene Eingabeelemente gleichzeitig. Mit <h:messages> kann man einen Bereich auf der Seite festlegen, in dem Meldungen für alle Eingabeelemente angezeigt werden.

Standard-Validatoren

Eingegebene Werte aus Formularen werden in der Apply Request Values Phase aus dem HTTP-Request zunächst in den View-Baum übertragen, um sie dann in der Process Validations Phase auf Gültigkeit zu überprüfen. Die einfachste Art der Validierung ist es sicherzustellen, dass überhaupt ein Wert eingegeben wurde. Dies geschieht mit dem Attribut "required", dass für jedes Eingabe-Element angeben werden kann.

<h:/inputText required="true"/>

Bei der Validierung wird geprüft, ob die Zeichenkette aus dem HTTP-Request die korrekten Zeichen enthält. Für einfache Prüfungen werden Standard-Validatoren als Elemente zur Verfügung gestellt.

<f:validateLength minimum="1" maximum="20" />
<f:validateLongRange minimum="-123456780" maximum="1234567890" />
<f:validateDoubleRange minimum="-0.5" maximum="0.5" />
<f:validateRegex pattern="((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,10})" />

Die Verwendung geschieht durch Einbettung in ein Eingabe-Element.

<h:inputText ...>
   <f:validateLength maximum="10"/>
</h:inputText>

Validator-Methoden in der Bean

Für eigene Prüfungen kann auf eine Validator-Methode in der ManagedBean verwiesen werden. Dies geschieht mit dem Attribut validator in dem entsprechenden Eingabe Element.

<h:inputText validator="#{bean.validateABC}" ... />

In der Bean wird dann eine Methode mit folgender Signatur erwartet, die zur Validierung herangezogen wird:

void validateABC (FacesContext context, UIComponent component, Object value) throws ValidatorException

Die Methode überprüft den eingegebenen Wert, der mit dem Parameter value übergeben wird und wirft eine ValidatorException mit der entsprechenden Fehlermeldung, wenn die Validierung fehl schlägt.

Eigene Validatoren

Soll ein Validator für mehrere Beans verwendet werden, so kann die Validator-Methode auch in einer eigenen Klasse definiert werden. Die Klasse muss mit @FacesValidator("phoneValidator") annotiert sein und die Schnittstelle Validator implementieren, die genau eine Methode validate(...) mit der o. g. Signatur vorschreibt. Die Zeichenkette "phoneValidator" als Annotationsattribut bezeichnet die Validator-ID. Referenziert wird der Validator unter dieser ID dann wie folgt:

<h:inputText ...>
   <f:validate validatorId="phoneValidator"/>
</h:inputText>

Stellt der Validator fest, dass die Eingabe nicht korrekt ist, so wird er eine ValidatorException werfen, in der die Fehlermeldung als FacesMessage gespeichert ist. Ein entsprechender Validator könnte wie folgt formuliert werden.

package berlin.britzke.crm;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

/**
 * Der ExampleValidator stellt sicher, dass in das validierte Formularfeld der
 * Wert "korrekter Wert" einegeben wird.
 * 
 * @author Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!
 */
@FacesValidator ("example")
public class ExampleValidator implements Validator {

	/**
	 * Wirft eine ValidatorException, wenn in der validierten Komponente nicht
	 * die Zeichenkette "korrekter Wert" erfasst wurde.
	 * 
	 * @see javax.faces.validator.Validator#validate(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent, java.lang.Object)
	 */
	@Override
	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {
		if (!((String) value).equals("korrekter Wert")) {
			throw new ValidatorException(
					new FacesMessage("Validierung fehlgeschlagen"));
		}
	}
}

Beim Rendern des HTML-Kodes werden die Fehlermeldungen aus dem FacesContext in die <h:message />-Elemente übertragen und somit angezeigt.