What happens in the registration process?
The register.xhtml JSF form captures the user input for new account registration. It validates the user input, binds the data to a Seam data component, and invokes a Seam UI event handler method when the form is submitted.
<s:validateAll>
<div class="entry">
<div class="label">
<h:outputLabel for="username">Username:</h:outputLabel>
</div>
<div class="input">
<h:inputText id="username" value="#{user.username}"/><br/>
<span class="errors"><h:message for="username" /></span>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="name">Real Name:</h:outputLabel>
</div>
<div class="input">
<h:inputText id="name" value="#{user.name}" /><br/>
<span class="errors"><h:message for="name" /></span>
</div>
</div>
</s:validateAll>
... ...
<div class="input">
<h:commandButton value="Register"
action="#{register.register}"
class="button"/>
<h:commandButton value="Cancel" action="login" class="button"/>
</div>
The form fields are bound to properties of a Seam component named
user
via JSF EL value binding expressions such as
#{user.username}
. The form submit button is bound
to the register()
method of the Seam component named
register
using the JSF method binding expression
#{register.register}
.
Notice that the input fields are enclosed by a <s:validateAll
tag. This tag is part of Seam's extension to JSF. It tells the Seam
runtime to validate those input fields when the form is submitted.
The validation conditions are specified on the entity bean classes
those input fields map to (e.g., here the validation condition is
on the User
class, see later).
This JSF form also includes <h:message>
tags that
will display the results of any JSF validation failures.
The User
class is an EJB 3.0 entity bean with a
@Name
annotation that binds the bean instance to a
context variable named user
. In addition to the standard
EJB 3.0 O/R mapping metadata, this bean features several Hibernate
Validator annotations such as
@NotNull
, @Length
. Due to the
<s:validateAll
tag in the form, these constraints are
automatically validated by Seam when the form is submitted. If the user
enters invalid data in the JSF form, the form will be redisplayed with
error messages.
@Entity
@Name("user")
@Scope(SESSION)
public class User implements Serializable
{
private String username;
private String password;
private String name;
public User(String name, String password, String username)
{
this.name = name;
this.password = password;
this.username = username;
}
public User() {}
@NotNull
@Length(max=100)
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@NotNull
@Length(min=5, max=15)
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
@Id
@Length(min=5, max=15)
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
RegisterAction
is an EJB 3.0 stateful session bean
bound to the Seam context variable named register
.
The register()
method is invoked when the form is
submitted.
@Stateful
@Scope(EVENT)
@Name("register")
public class RegisterAction implements Register
{
@In
private User user;
@PersistenceContext
private EntityManager em;
@In(create=true)
private transient FacesMessages facesMessages;
private String verify;
public String register()
{
if ( user.getPassword().equals(verify) )
{
List existing = em.createQuery("select username from User " +
"where username=:username")
.setParameter("username", user.getUsername())
.getResultList();
if (existing.size()==0)
{
em.persist(user);
return "login";
}
else
{
facesMessages.add("username #{user.username} already exists");
return null;
}
}
else
{
facesMessages.add("re-enter your password");
verify=null;
return null;
}
}
public String getVerify()
{
return verify;
}
public void setVerify(String verify)
{
this.verify = verify;
}
@Destroy @Remove
public void destroy() {}
}
The @In
annotations inject Seam components into the RegisterAction
bean. The user
component is our entity bean, of course. The facesMessages
component is a built-in Seam component that makes it very easy to display templated and localized
messages to the user, even when redirect after post is used.