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 1.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.
001.
package
com.vaannila.domain;
002.
003.
import
java.io.Serializable;
004.
005.
import
javax.persistence.Column;
006.
import
javax.persistence.Entity;
007.
import
javax.persistence.GeneratedValue;
008.
import
javax.persistence.Id;
009.
import
javax.persistence.Table;
010.
011.
import
org.hibernate.validator.Length;
012.
import
org.hibernate.validator.NotEmpty;
013.
014.
@Entity
015.
@Table
(name =
"USER"
)
016.
public
class
User
implements
Serializable {
017.
018.
private
static
final
long
serialVersionUID = 6295524232169619097L;
019.
020.
private
Long id;
021.
022.
private
String name;
023.
024.
private
String password;
025.
026.
private
String gender;
027.
028.
private
String country;
029.
030.
private
String aboutYou;
031.
032.
private
Boolean mailingList;
033.
034.
@Id
035.
@GeneratedValue
036.
@Column
(name =
"USER_ID"
)
037.
public
Long getId() {
038.
return
id;
039.
}
040.
041.
public
void
setId(Long id) {
042.
this
.id = id;
043.
}
044.
045.
@NotEmpty
046.
@Length
(max=
50
)
047.
@Column
(name =
"USER_NAME"
, nullable =
false
, length =
50
)
048.
public
String getName() {
049.
return
name;
050.
}
051.
052.
public
void
setName(String name) {
053.
this
.name = name;
054.
}
055.
056.
@Length
(min=
6
, max=
10
)
057.
@Column
(name =
"USER_PASSWORD"
, nullable =
false
, length =
10
)
058.
public
String getPassword() {
059.
return
password;
060.
}
061.
062.
public
void
setPassword(String password) {
063.
this
.password = password;
064.
}
065.
066.
@NotEmpty
(message=
"Please select a gender"
)
067.
@Column
(name =
"USER_GENDER"
)
068.
public
String getGender() {
069.
return
gender;
070.
}
071.
072.
public
void
setGender(String gender) {
073.
this
.gender = gender;
074.
}
075.
076.
@NotEmpty
(message=
"Please select a country"
)
077.
@Column
(name =
"USER_COUNTRY"
)
078.
public
String getCountry() {
079.
return
country;
080.
}
081.
082.
public
void
setCountry(String country) {
083.
this
.country = country;
084.
}
085.
086.
@NotEmpty
087.
@Length
(max=
100
)
088.
@Column
(name =
"USER_ABOUT_YOU"
, length =
100
)
089.
public
String getAboutYou() {
090.
return
aboutYou;
091.
}
092.
093.
public
void
setAboutYou(String aboutYou) {
094.
this
.aboutYou = aboutYou;
095.
}
096.
097.
@Column
(name =
"USER_MAILING_LIST"
)
098.
public
Boolean getMailingList() {
099.
return
mailingList;
100.
}
101.
102.
public
void
setMailingList(Boolean mailingList) {
103.
this
.mailingList = mailingList;
104.
}
105.
106.
}
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.
01.
@NotEmpty
(message=
"Please select a gender"
)
02.
@Column
(name =
"USER_GENDER"
)
03.
public
String getGender() {
04.
return
gender;
05.
}
06.
07.
@NotEmpty
(message=
"Please select a country"
)
08.
@Column
(name =
"USER_COUNTRY"
)
09.
public
String getCountry() {
10.
return
country;
11.
}
In the UserAction class you need to specify the @Valid annotation for the domain object that needs to be validated.
01.
package
com.vaannila.web;
02.
03.
import
java.util.ArrayList;
04.
import
java.util.List;
05.
06.
import
org.hibernate.validator.Valid;
07.
08.
import
com.opensymphony.xwork2.ActionSupport;
09.
import
com.vaannila.dao.UserDAO;
10.
import
com.vaannila.dao.UserDAOImpl;
11.
import
com.vaannila.domain.User;
12.
13.
public
class
UserAction
extends
ActionSupport {
14.
15.
private
static
final
long
serialVersionUID = -6659925652584240539L;
16.
17.
@Valid
18.
private
User user;
19.
private
List<User> userList =
new
ArrayList<User>();
20.
private
UserDAO userDAO =
new
UserDAOImpl();
21.
22.
public
String add()
23.
{
24.
userDAO.saveUser(user);
25.
return
SUCCESS;
26.
}
27.
28.
public
String list()
29.
{
30.
userList = userDAO.listUser();
31.
return
SUCCESS;
32.
}
33.
34.
public
User getUser() {
35.
return
user;
36.
}
37.
38.
public
void
setUser(User user) {
39.
this
.user = user;
40.
}
41.
42.
public
List<User> getUserList() {
43.
return
userList;
44.
}
45.
46.
public
void
setUserList(List<User> userList) {
47.
this
.userList = userList;
48.
}
49.
50.
}
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.
01.
<!DOCTYPE struts PUBLIC
02.
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
04.
05.
<
struts
>
06.
<
package
name
=
"default"
extends
=
"hibernate-default"
>
07.
<
action
name
=
"addUser"
method
=
"add"
class
=
"com.vaannila.web.UserAction"
>
08.
<
result
name
=
"input"
>/register.jsp</
result
>
09.
<
result
name
=
"success"
type
=
"redirect"
>listUser</
result
>
10.
</
action
>
11.
<
action
name
=
"listUser"
method
=
"list"
class
=
"com.vaannila.web.UserAction"
>
12.
<
interceptor-ref
name
=
"basicStackHibernate"
/>
13.
<
result
name
=
"success"
>/register.jsp</
result
>
14.
</
action
>
15.
</
package
>
16.
</
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.
01.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
02.
pageEncoding="ISO-8859-1"%>
03.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
04.
<%@taglib uri="/struts-tags" prefix="s"%>
05.
<
html
>
06.
<
head
>
07.
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=ISO-8859-1"
>
08.
<
title
>Registration Page</
title
>
09.
<
s:head
/>
10.
<
style
type
=
"text/css"
>
11.
@import url(style.css);
12.
</
style
>
13.
</
head
>
14.
<
body
>
15.
<
s:actionerror
/>
16.
<
s:form
action
=
"addUser"
>
17.
<
s:hidden
name
=
"user.id"
/>
18.
<
s:textfield
key
=
"user.name"
/>
19.
<
s:password
key
=
"user.password"
/>
20.
<
s:select
key
=
"user.gender"
list
=
"{'Male','Female'}"
headerKey
=
""
21.
headerValue
=
"Select"
label
=
"Gender"
/>
22.
<
s:select
key
=
"user.country"
list
=
"{'India','USA','UK'}"
headerKey
=
""
23.
headerValue
=
"Select"
label
=
"Country"
/>
24.
<
s:textarea
key
=
"user.aboutYou"
/>
25.
<
s:checkbox
key
=
"user.mailingList"
26.
label
=
"Would you like to join our mailing list?"
/>
27.
<
s:submit
/>
28.
</
s:form
>
29.
30.
31.
<
s:if
test="userList.size() > 0">
32.
<
div
class
=
"content"
>
33.
<
table
class
=
"userTable"
cellpadding
=
"5px"
>
34.
<
tr
class
=
"even"
>
35.
<
th
>Name</
th
>
36.
<
th
>Gender</
th
>
37.
<
th
>Country</
th
>
38.
<
th
>About You</
th
>
39.
<
th
>Mailing List</
th
>
40.
</
tr
>
41.
<
s:iterator
value
=
"userList"
status
=
"userStatus"
>
42.
<
tr
43.
class
=
"<s:if test="
#userStatus.odd == true ">odd</
s:if
><
s:else
>even</
s:else
>">
44.
<
td
><
s:property
value
=
"name"
/></
td
>
45.
<
td
><
s:property
value
=
"gender"
/></
td
>
46.
<
td
><
s:property
value
=
"country"
/></
td
>
47.
<
td
><
s:property
value
=
"aboutYou"
/></
td
>
48.
<
td
><
s:property
value
=
"mailingList"
/></
td
>
49.
</
tr
>
50.
</
s:iterator
>
51.
</
table
>
52.
</
div
>
53.
</
s:if
>
54.
</
body
>
55.
</
html
>
The key values should be specified in the UserAction.properties file and this file should be saved next to the UserAction.java file.
1.
user.name=User Name
2.
user.password=Password
3.
user.aboutYou=About You
4.
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.
Everything else remains the same as the previous example ( Struts 2 Hibernate Integration ).
No comments:
Post a Comment