The Hibernator
Validator framework follows the DRY (Don't Repeat Yourself) principle. Using
Hibernator Validator you need to specify the constraints using annotations in
the domain object. Once you specify the constraints you can use it in any layer
of your application without duplicating it.
Hibernate Validator comes with basic
buit-in constraints like @Length(min=, max=), @Max(value=),
@Min(value=), @NotNull, @NotEmpty and so on. You can
also build your own constraints easily.
In this example you will see how to
integrate Struts 2 with Hibernator Validator using the Full
Hibernate Plugin 4 GA.
You need to have all the lib files
that we used in the previous example ( Struts 2 Hibernate Integration ).
The domain object User, with the
validation constraints is shown below.
0package com.vaannila.domain;
0
0import java.io.Serializable;
0
0import javax.persistence.Column;
0import javax.persistence.Entity;
0import javax.persistence.GeneratedValue;
0import javax.persistence.Id;
0import javax.persistence.Table;
0
0import org.hibernate.validator.Length;
0import org.hibernate.validator.NotEmpty;
0
0@Entity
0@Table(name = "USER")
0public class User implements Serializable {
0
0private static final long serialVersionUID = 6295524232169619097L;
0
0private Long id;
0
0private String name;
0
0private String
password;
0
0private String gender;
0
0private String country;
0
0private String
aboutYou;
0
0private Boolean
mailingList;
0
0@Id
0@GeneratedValue
0@Column(name = "USER_ID")
0public Long getId() {
0return id;
0}
0
0public void setId(Long id) {
0this.id = id;
0}
0
0@NotEmpty
0@Length(max=50)
0@Column(name = "USER_NAME", nullable = false, length = 50)
0public String
getName() {
0return name;
0}
0
0public void setName(String name) {
0this.name = name;
0}
0
0@Length(min=6, max=10)
0@Column(name = "USER_PASSWORD", nullable = false, length = 10)
0public String
getPassword() {
0return password;
0}
0
0public void setPassword(String password) {
0this.password = password;
0}
0
0@NotEmpty(message="Please
select a gender")
0@Column(name = "USER_GENDER")
0public String
getGender() {
0return gender;
0}
07
07public void setGender(String gender) {
07this.gender = gender;
07}
07
07@NotEmpty(message="Please
select a country")
07@Column(name = "USER_COUNTRY")
07public String
getCountry() {
07return country;
08}
08
08public void setCountry(String country) {
08this.country = country;
08}
08
08@NotEmpty
08@Length(max=100)
08@Column(name = "USER_ABOUT_YOU", length = 100)
08public String
getAboutYou() {
09return aboutYou;
09}
09
09public void setAboutYou(String aboutYou) {
09this.aboutYou = aboutYou;
09}
09
09@Column(name = "USER_MAILING_LIST")
09public Boolean
getMailingList() {
09return mailingList;
10}
1
1public void setMailingList(Boolean mailingList) {
1this.mailingList =
mailingList;
1}
1
1}
As you can see in
addition to the JPA annotations you have the Hibernator Validator constraints.
The @NotEmpty constraint checks if the String is not null or not empty.
The @Length(min=6,
max=10) constraint checks whether the lenght
is within the min max range.
The validation messages are auto
generated by the plug-in. You can also override the default message using the message attribute of the constraint. For gender and country properties we specify a customized message.
@NotEmpty(message="Please
select a gender")
@Column(name = "USER_GENDER")
public String
getGender() {
return gender;
}
@NotEmpty(message="Please
select a country")
@Column(name = "USER_COUNTRY")
public String
getCountry() {
return country;
}
In the UserAction class you need to specify the @Valid annotation for the domain object that needs to be validated.
package com.vaannila.web;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.validator.Valid;
import com.opensymphony.xworkActionSupport;
import com.vaannila.dao.UserDAO;
import com.vaannila.dao.UserDAOImpl;
import com.vaannila.domain.User;
public class UserAction extends ActionSupport {
private static final long serialVersionUID = -6659925652584240539L;
@Valid
private User user;
private List<User>
userList = new ArrayList<User>();
private UserDAO userDAO
= new UserDAOImpl();
public String add()
{
userDAO.saveUser(user);
return SUCCESS;
}
public String list()
{
userList = userDAO.listUser();
return SUCCESS;
}
public User getUser()
{
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User>
getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
Since we use the Hibernate
Plugin you need to extend the package form hibernate-default package. The hibernate-default package has the following three interceptor stacks.
·
basicStackHibernate: Struts2 basickStack + Hibernate session and transaction capability.
·
defaultStackHibernate: Struts2 defaultStack (no validations) + Hibernate validation, session
and transaction capability.
·
defaultStackHibernateStrutsValidation: Struts2 defaultStack (with validation) + basicStackHibernate.
The struts
configuration file is shown below.
<!DOCTYPE struts PUBLIC
"-//Apache Software
Foundation//DTD Struts Configuration 0//EN"
<struts>
<package name="default" extends="hibernate-default">
<action name="addUser" method="add"class="com.vaannila.web.UserAction">
<result name="input">/register.jsp</result>
<result name="success" type="redirect">listUser</result>
</action>
<action name="listUser" method="list"class="com.vaannila.web.UserAction">
<interceptor-ref name="basicStackHibernate" />
<result name="success">/register.jsp</result>
</action>
</package>
</struts>
By default the defaultStackHibernate interceptor stack will be used. In the addUser action we use this inteceptor stack since we need validation capability
and during the listUser action action we usebasicStackHibernate because we don't need validation capability this time.
In the register.jsp page instead of using the name attribute to specify the property value we use the keyattribute. This is
need for the default validation messages to be generated.
<%@ page language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 01 Transitional//EN" "http://www.worg/TR/html4/loose.dtd">
<%@taglib
uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
<title>Registration
Page</title>
<s:head />
<style type="text/css">
@import url(style.css);
</style>
</head>
<body>
<s:actionerror/>
<s:form action="addUser">
<s:hidden name="user.id" />
<s:textfield key="user.name" />
<s:password key="user.password" />
<s:select key="user.gender" list="{'Male','Female'}" headerKey=""
headerValue="Select" label="Gender" />
<s:select key="user.country" list="{'India','USA','UK'}" headerKey=""
headerValue="Select" label="Country" />
<s:textarea key="user.aboutYou" />
<s:checkbox key="user.mailingList"
label="Would you like to join our mailing
list?" />
<s:submit />
</s:form>
<s:if test="userList.size()
> 0">
<div class="content">
<table class="userTable" cellpadding="5px">
<tr class="even">
<th>Name</th>
<th>Gender</th>
<th>Country</th>
<th>About You</th>
<th>Mailing List</th>
</tr>
<s:iterator value="userList" status="userStatus">
<tr
class="<s:if test="#userStatus.odd == true ">odd</s:if><s:else>even</s:else>">
<td><s:property value="name" /></td>
<td><s:property value="gender" /></td>
<td><s:property value="country" /></td>
<td><s:property value="aboutYou" /></td>
<td><s:property value="mailingList" /></td>
</tr>
</s:iterator>
</table>
</div>
</body>
</html>
The key values should be specified in
the UserAction.properties file and this file
should be saved next to the UserAction.java file.
user.name=User Name
user.password=Password
user.aboutYou=About You
user.mailingList=Mailing List
The default
validation messages will be generated using the field labels as prefix.
When you execute
the example and submit the form without entering any values you will see the
following validation messages.
The validation messge for the fields User
Name, Password and About
You has the field label before the
default validation error message. This is because we specified the key values
in theUserAction.properties file. If you only want the validation message to be displayed then don't
specify an entry for that field in the properties file. Here the gender and the
country fields have only the customized error messages and not the field
labels.
No comments:
Post a Comment