Dieser Inhalt ist in der von Ihnen ausgewählten Sprache nicht verfügbar.

Chapter 11. JSF form validation in Seam


In plain JSF, validation is defined in the view:
<h:form>
  <h:messages/>

  <div>
    Country:
    <h:inputText value="#{location.country}" required="true">
      <my:validateCountry/>
    </h:inputText>
  </div>
    
  <div>
    Zip code:
    <h:inputText value="#{location.zip}" required="true">
      <my:validateZip/>
    </h:inputText>
  </div>

  <h:commandButton/>
</h:form>
Copy to Clipboard Toggle word wrap
In practice, this approach usually violates DRY, since most "validation" actually enforces constraints that are part of the data model, and exist all the way down to the database schema definition. Seam provides support for model-based constraints defined with Hibernate Validator.
We will begin by defining our constraints, on our Location class:
public class Location {
    private String country;
    private String zip;
  
    @NotNull
    @Length(max=30)
    public String getCountry() { return country; }
    public void setCountry(String c) { country = c; }

    @NotNull
    @Length(max=6)
    @Pattern("^\d*$")
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }
}
Copy to Clipboard Toggle word wrap
In practice, it may be more elegant to use custom constraints rather than those built into Hibernate Validator:
public class Location {
    private String country;
    private String zip;
  
    @NotNull
    @Country
    public String getCountry() { return country; }
    public void setCountry(String c) { country = c; }

    @NotNull
    @ZipCode
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }
}
Copy to Clipboard Toggle word wrap
Whichever method we choose, we no longer need specify the validation type to be used in the JSF page. Instead, we use <s:validate> to validate against the constraint defined on the model object.
<h:form>
  <h:messages/>

  <div>
    Country:
    <h:inputText value="#{location.country}" required="true">
      <s:validate/>
    </h:inputText>
  </div>
  
  <div>
    Zip code:
    <h:inputText value="#{location.zip}" required="true">
      <s:validate/>
    </h:inputText>
  </div>
  
  <h:commandButton/>

</h:form>
Copy to Clipboard Toggle word wrap

Note

Specifying @NotNull on the model does not eliminate the need for required="true" to appear on the control. This is a limitation of the JSF validation architecture.
This approach defines constraints on the model, and presents constraint violations in the view.
The design is better, but not much less verbose than our initial design. Now, we will use <s:validateAll>:
<h:form>
    
  <h:messages/>

  <s:validateAll>

  <div>
    Country:
    <h:inputText value="#{location.country}" required="true"/>
  </div>

  <div>
    Zip code:
    <h:inputText value="#{location.zip}" required="true"/>
  </div>

  <h:commandButton/>

  </s:validateAll>

</h:form>
Copy to Clipboard Toggle word wrap
This tag adds an <s:validate> to every input in the form. In a large form, this can save a lot of typing.
Next, we need to display feedback to the user when validation fails. Currently, all messages are displayed at the top of the form. To correlate the message with an input, you must define a label by using the standard label attribute on the input component.
<h:inputText value="#{location.zip}" required="true" label="Zip:"> 
  <s:validate/> 
</h:inputText>
Copy to Clipboard Toggle word wrap
Inject this value into the message string with the placeholder {0} (the first and only parameter passed to a JSF message for a Hibernate Validator restriction). See the internationalization section for more information on where to define these messages.

Note

validator.length={0} length must be between {min} and {max}
We would prefer the message to be displayed beside the field with the error, highlight the field and label, and display an image next to the field. In plain JSF, only the first is possible. We also want to display a colored asterisk beside the label of each required form field.
This is a lot of functionality for each field. We do not want to specify highlighting and the layout of the image, message, and input field for every field on the form, so we specify the layout in a facelets template:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:s="http://jboss.com/products/seam/taglib">           
  <div>
  
    <s:label styleClass="#{invalid?'error':''}">
      <ui:insert name="label"/>
      <s:span styleClass="required" rendered="#{required}">*</s:span>
    </s:label>
        
    <span class="#{invalid?'error':''}">
      <h:graphicImage value="/img/error.gif" rendered="#{invalid}"/>
      <s:validateAll>
        <ui:insert/>
      </s:validateAll>
    </span>
        
    <s:message styleClass="error"/>
        
  </div>
    
</ui:composition>
Copy to Clipboard Toggle word wrap
We can include this template for each of our form fields by using <s:decorate>:
<h:form>
  <h:messages globalOnly="true"/>

    <s:decorate template="edit.xhtml">
        <ui:define name="label">Country:</ui:define>
        <h:inputText value="#{location.country}" required="true"/>
    </s:decorate>
    
    <s:decorate template="edit.xhtml">
        <ui:define name="label">Zip code:</ui:define>
        <h:inputText value="#{location.zip}" required="true"/>
    </s:decorate>

    <h:commandButton/>

</h:form>
Copy to Clipboard Toggle word wrap
Finally, we can use RichFaces Ajax to display validation messages while the user navigates around the form:
<h:form>
  <h:messages globalOnly="true"/>

    <s:decorate id="countryDecoration" template="edit.xhtml">
        <ui:define name="label">Country:</ui:define>
        <h:inputText value="#{location.country}" required="true">
            <a:support event="onblur" reRender="countryDecoration" 
                       bypassUpdates="true"/>
        </h:inputText>
    </s:decorate>
    
    <s:decorate id="zipDecoration" template="edit.xhtml">
        <ui:define name="label">Zip code:</ui:define>
        <h:inputText value="#{location.zip}" required="true">
            <a:support event="onblur" reRender="zipDecoration" 
                       bypassUpdates="true"/>
        </h:inputText>
    </s:decorate>

    <h:commandButton/>

</h:form>
Copy to Clipboard Toggle word wrap
Stylistically, it is better to define explicit IDs for important page controls, particularly if you want automated UI testing. If explicit IDs are not provided, JSF will generate its own — but they will not remain static if anything on the page is changed.
<h:form id="form">
  <h:messages globalOnly="true"/>

    <s:decorate id="countryDecoration" template="edit.xhtml">
    <ui:define name="label">Country:</ui:define>
      <h:inputText id="country" value="#{location.country}" 
                   required="true">
        <a:support event="onblur" reRender="countryDecoration" 
                   bypassUpdates="true"/>
      </h:inputText>
    </s:decorate>
    
    <s:decorate id="zipDecoration" template="edit.xhtml">
      <ui:define name="label">Zip code:</ui:define>
      <h:inputText id="zip" value="#{location.zip}" required="true">
        <a:support event="onblur" reRender="zipDecoration" 
                   bypassUpdates="true"/>
      </h:inputText>
    </s:decorate>

    <h:commandButton/>

</h:form>
Copy to Clipboard Toggle word wrap
If you want to specify a different message to be displayed when validation fails, you can use the Seam message bundle with the Hibernate Validator:
public class Location {
    private String name;
    private String zip;
  
    // Getters and setters for name

    @NotNull
    @Length(max=6)
    @ZipCode(message="#{messages['location.zipCode.invalid']}")
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }
}
Copy to Clipboard Toggle word wrap
 location.zipCode.invalid = The zip code is not valid for #{location.name}
Copy to Clipboard Toggle word wrap
Nach oben
Red Hat logoGithubredditYoutubeTwitter

Lernen

Testen, kaufen und verkaufen

Communitys

Über Red Hat Dokumentation

Wir helfen Red Hat Benutzern, mit unseren Produkten und Diensten innovativ zu sein und ihre Ziele zu erreichen – mit Inhalten, denen sie vertrauen können. Entdecken Sie unsere neuesten Updates.

Mehr Inklusion in Open Source

Red Hat hat sich verpflichtet, problematische Sprache in unserem Code, unserer Dokumentation und unseren Web-Eigenschaften zu ersetzen. Weitere Einzelheiten finden Sie in Red Hat Blog.

Über Red Hat

Wir liefern gehärtete Lösungen, die es Unternehmen leichter machen, plattform- und umgebungsübergreifend zu arbeiten, vom zentralen Rechenzentrum bis zum Netzwerkrand.

Theme

© 2025 Red Hat