Seam Data Validation

Exclusive offer: get 50% off this eBook here
Seam 2.x Web Development

Seam 2.x Web Development — Save 50%

Build robust web applications with Seam, Facelets, and RichFaces using the JBoss application server

$23.99    $12.00
by David Salter | May 2009 | Java Open Source Web Development

Seam can act as JSF backing beans and as the glue between our server-tier Session Beans and our web-tier JSF pages. Unfortunately, though, users could easily break our sample application by entering invalid data (for example, entering blank values or non-numeric values into the edit boxes). Seam provides validation tools to help us to make our application more robust and provide feedback to our users. In this article by David Salter, let's look at these tools.

Data validation

In order to perform consistent data validation, we would ideally want to perform all data validation within our data model. We want to perform data validation in our data model so that we can then keep all of the validation code in one place, which should then make it easier to keep it up-to-date if we ever change our minds about allowable data values.

Seam makes extensive use of the Hibernate validation tools to perform validation of our domain model. The Hibernate validation tools grew from the Hibernate project (http://www.hibernate.org) to allow the validation of entities before they are persisted to the database. To use the Hibernate validation tools in an application, we need to add hibernate-validator.jar into the application's class path, after which we can use annotations to define the validation that we want to use for our data model. Let's look at a few validations that we can add to our sample Seam Calculator application.

In order to implement data validation with Seam, we need to apply annotations either to the member variables in a class or to the getter of the member variables. It's good practice to always apply these annotations to the same place in a class. Hence, throughout this article, we will always apply our annotation to the getter methods within classes.

In our sample application, we are allowing numeric values to be entered via edit boxes on a JSF form. To perform data validation against these inputs, there are a few annotations that can help us.

Annotation

Description

@Min

The @Min annotation allows a minimum value for a numeric variable to be specified. An error message to be displayed if the variable's value is less than the specified minimum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be greater than or equal to ...).

@Min(value=0, message="...")

@Max

The @Max annotation allows a maximum value for a numeric variable to be specified. An error message to be displayed if the variable's value is greater than the specified maximum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be less than or equal to ...).

@Max(Value=100, message="...")

@Range

The @Range annotation allows a numeric range-that is, both minimum and maximum values-to be specified for a variable. An error message to be displayed if the variable's value is outside the specified range can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be between ... and ...).

@Range(min=0, max=10, message="...")

At this point, you may be wondering why we need to have an @Range validator, when by combining the @Min and @Max validators, we can get a similar effect. If you want a different error message to be displayed when a variable is set above its maximum value as compared to the error message that is displayed when it is set below its minimum value, then the @Min and @Max annotations should be used. If you are happy with the same error message being displayed when a variable is set outside its minimum or maximum values, then the @Range validator should be used. Effectively, the @Min and @Max validators are providing a finer level of error message provision than the @Range validator.

The following code sample shows how these annotations can be applied to a sample application, to add basic data validation to our user inputs.

package com.davidsalter.seamcalculator;

import java.io.Serializable;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.faces.FacesMessages;
import org.hibernate.validator.Max;
import org.hibernate.validator.Min;
import org.hibernate.validator.Range;

@Name("calculator")
public class Calculator implements Serializable {

private double value1;
private double value2;
private double answer;
@Min(value=0)
@Max(value=100)
public double getValue1() {
return value1;
}
public void setValue1(double value1) {
this.value1 = value1;
}
@Range(min=0, max=100)
public double getValue2() {
return value2;
}
public void setValue2(double value2) {
this.value2 = value2;
}
public double getAnswer() {
return answer;
}
...
}

Displaying errors to the user

In the previous section, we saw how to add data validation to our source code to stop invalid data from being entered into our domain model. Now that we have reached a level of data validation, we need to provide feedback to the user to inform them of any invalid data that they have entered.

JSF applications have the concept of messages that can be displayed associated with different components. For example, if we have a form asking for a date of birth to be entered, we could display a message next to the entry edit box if an invalid date were entered. JSF maintains a collection of these error messages, and the simplest way of providing feedback to the user is to display a list of all of the error messages that were generated as a part of the previous operation.

In order to obtain error messages within the JSF page, we need to tell JSF which components we want to be validated against the domain model. This is achieved by using the <s:validate/> or <s:validateAll/> tags. These are Seam-specific tags and are not a part of the standard JSF runtime. In order to use these tags, we need to add the following taglib reference to the top of the JSF page.

<%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %>

In order to use this tag library, we need to add a few additional JAR files into the WEB-INF/lib directory of our web application, namely:

  • jboss-el.jar
  • jboss-seam-ui.jar
  • jsf-api.jar
  • jsf-impl.jar

This tag library allows us to validate all of the components (<s:validateAll/>) within a block of JSF code, or individual components (<s:validate/>) within a JSF page.

To validate all components within a particular scope, wrap them all with the <s:validateAll/> tag as shown here:

<h:form>
<s:validateAll>
<h:inputText value="..." />
<h:inputText value="..." />
</s:validateAll>
</h:form>

To validate individual components, embed the <s:validate/> tag within the component, as shown in the following code fragment.

<h:form>
<h:inputText value="..." >
<s:validate/>
</h:inputText>

<h:inputText value="..." >
<s:validate/>
</h:inputText>
</h:form>

After specifying that we wish validation to occur against a specified set of controls, we can display error messages to the user. JSF maintains a collection of errors on a page, which can be displayed in its entirety to a user via the <h:messages/> tag.

Seam 2.x Web Development

It can sometimes be useful to show a list of all of the errors on a page, but it isn't very useful to the user as it is impossible for them to say which error relates to which control on the form. Seam provides some additional support at this point to allow us to specify the formatting of a control to indicate error or warning messages to users.

Seam provides three different JSF facets (<f:facet/>) to allow HTML to be specified both before and after the offending input, along with a CSS style for the HTML. Within these facets, the <s:message/> tag can be used to output the message itself. This tag could be applied either before or after the input box, as per requirements.

Facet

Description

beforeInvalidField

This facet allows HTML to be displayed before the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred.

<f:facet name="beforeInvalidField">

...

</f:facet>

afterInvalidField

This facet allows HTML to be displayed after the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred.

<f:facet name="afterInvalidField">

...

</f:facet>

aroundInvalidField

This facet allows the CSS style of the text surrounding the input that is in error to be specified.

<f:facet name="aroundInvalidField">

...

</f:facet>

In order to specify these facets for a particular field, the <s:decorate/>  tag must be specified outside the facet scope.

<s:decorate>
<f:facet name="aroundInvalidField">
<s:span styleClass="invalidInput"/>
</f:facet>
<f:facet name="beforeInvalidField">
<f:verbatim>**</f:verbatim>
</f:facet>
<f:facet name="afterInvalidField">
<s:message/>
</f:facet>
<h:inputText value="#{calculator.value1}" required="true" >
<s:validate/>
</h:inputText>
</s:decorate>

In the preceding code snippet, we can see that a CSS style called invalidInput is being applied to any error or warning information that is to be displayed regarding the <inputText/> field. An erroneous input field is being adorned with a double asterisk (**) preceding the edit box, and the error message specific to the inputText field after is displayed in the edit box.

Seam 2.x Web Development Build robust web applications with Seam, Facelets, and RichFaces using the JBoss application server
Published: April 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Applying these features to our sample application, the calc.jsp file will appear as follows:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %>

<html>
<head>
<title>Seam Calculator</title>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<f:view>
<h:form>
<h:panelGrid columns="2">
Value 1:
<s:decorate>
<f:facet name="aroundInvalidField">
<s:span styleClass="invalidInput"/>
</f:facet>
<f:facet name="beforeInvalidField">
<f:verbatim>**</f:verbatim>
</f:facet>
<f:facet name="afterInvalidField">
<s:message/>
</f:facet>
<h:inputText value="#{calculator.value1}"
required="true" >
<s:validate/>
</h:inputText>
</s:decorate>
Value 2:
<s:decorate>
<f:facet name="aroundInvalidField">
<s:span styleClass="invalidInput"/>
</f:facet>
<f:facet name="beforeInvalidField">
<f:verbatim>**</f:verbatim>
</f:facet>
<f:facet name="afterInvalidField">
<s:message/>
</f:facet>
<h:inputText value="#{calculator.value2}"
required="true">
<s:validate/>
</h:inputText>
</s:decorate>
Adding them together gives:
<h:outputText value="#{calculator.answer}"/>
</h:panelGrid>
<h:commandButton value="Add"
action="#{calcAction.calculate}"/>
<h:messages/>
</h:form>
</f:view>
</body>
</html>

To allow validation information to be displayed, we made several changes to this file and to our web application. These changes are listed here:

  • Adding the Seam UI tag library to the header of the JSF page.
  • Specifying which objects need to be validated, by using the <s:validate/> or <s:validateAll/> tags.
  • Defining the three different facets that specify the formatting and output of the error message for each field. These facets must be surrounded by the <s:decorate/> tag.
  • Adding the Seam and third-party JARs into the WEB-INF/lib directory of the web application.

The JSF messages collection

So far, we've only added messages to the JSF messages collection via Hibernate validators that are applied to entities within our domain model. Sometimes, it can be useful to add a message that can be displayed irrespective of any errors or input controls on a form to the messages collection. The JSF messages collection is one of Seam's in-built components and is named org.jboss.seam.faces.facesMessages.

@Name("org.jboss.seam.faces.facesMessages")

This in-built component can easily be accessed within Seam applications by using the FacesMessages().instance() method. For example:

FacesMessages.instance().add("Phew, that was a lot of maths !!");

If we add all of our Hibernate validators to our Calculator.java class, the code will look as follows:

package com.davidsalter.seamcalculator;
import java.io.Serializable;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.faces.FacesMessages;
import org.hibernate.validator.Max;
import org.hibernate.validator.Min;
import org.hibernate.validator.Range;
@Name("calculator")
public class Calculator implements Serializable {
private double value1;
private double value2;
private double answer;
@Min(value=0)
@Max(value=100)
public double getValue1() {
return value1;
}
public void setValue1(double value1) {
this.value1 = value1;
}
@Range(min=0, max=100)
public double getValue2() {
return value2;
}
public void setValue2(double value2) {
this.value2 = value2;
}
public double getAnswer() {
return answer;
}
public void add() {
this.answer = value1 + value2;
//Access the "org.jboss.seam.faces.facesMessages" component
and add a message into it.
FacesMessages.instance().add("Phew, that was a lot of
maths !!");
}
}

In this code, we have added validators to the input data and then added a custom message into the JSF messages collection, to be displayed when a successful calculation was performed.

Building and testing the validating Seam calculator

In order to build and test the validating Seam calculator, we need to copy the additional JAR files (namely, hibernate-validator.jar, jboss-el.jar, jboss-seam-ui.jar, jsf-api.jar, and jsf-impl.jar) into the /lib directory of the sample project.

To build and deploy the project onto the JBoss Application Server, we need to execute the deploy ant target.

Seam 2.x Web Development

To view the application in the browser, navigate to http://localhost:8080/SeamCalculator/calc.seam.

If any invalid data is entered into the web application, this is picked up by the Hibernate validators and displayed on the form, both next to the field containing the error and in a list at the bottom of the page, which shows all of the errors on the page.

Seam 2.x Web Development

In the previous screenshot, you can see that the Hibernate validator has done its job correctly and added an error message informing the user that Value 2 is invalid as abc is not a valid number. While this is technically correct, the error message is very user-unfriendly and would probably result with many unhappy customers! For the moment, the important thing to note is that we have performed validation on user input and provided an error message when the validation fails.

When valid information is entered into the fields and the Add button is clicked, the two inputs are added together and displayed along with a custom error message that was added to the JSF messages collection.

Seam 2.x Web Development

Summary

We looked at how to add validation to Seam components and how to display validation errors and special messages on web pages, both around input components and in a list on the page. In the sample application that we built in this article, everything took place within a single JSF page.

Seam 2.x Web Development Build robust web applications with Seam, Facelets, and RichFaces using the JBoss application server
Published: April 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


David Salter

David Salter is an enterprise software developer who has been developing software professionally since 1991. His relationship with Java goes right back to the beginning, using Java 1.0 to write desktop applications and applets for interactive websites.

David has been developing Enterprise Java applications using both the Java EE standards and open source solutions for the last 10 years.

David is the co-author of Building SOA-based Composite Applications using NetBeans and the author of Seam 2.x Web Development.

Books From Packt

 

Practical Plone 3: A Beginner's Guide to Building Powerful Websites
Practical Plone 3: A Beginner's Guide to Building Powerful Websites

WordPress Plugin Development: Beginner's Guide
WordPress Plugin Development: Beginner's Guide

Spring 2.5 Aspect Oriented Programming
Spring 2.5 Aspect Oriented Programming

Spring Web Flow 2 Web Development
Spring Web Flow 2 Web Development

Grails 1.1 Web Application Development
Grails 1.1 Web Application Development

Drools JBoss Rules 5.0 Developer's Guide
Drools JBoss Rules 5.0 Developer's Guide

Django 1.0 Website Development
Django 1.0 Website Development

Learning jQuery 1.3
Learning jQuery 1.3

 

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software