To learn any web framework starting with a HelloWorld application is a good idea. Once you have some familiarity with the framework configuration, it's better to do a CRUD(Create,Read,Update,Delete) application which covers various aspects of a web framework like Validation, Request URL Mappings, Request Parameter Binding, Pre-populating forms etc.
Now I am going to explain how to write a Simple CRUD application using SpringMVC3, Hibernate and MySQL.
Our Application is ContactsManagement where you can view or search contacts, create new contacts, edit or delete existing contacts.
Step#1: Create the CONTACTS Table
01.
CREATE
TABLE
CONTACTS
02.
(
03.
id
int
(10) unsigned
NOT
NULL
AUTO_INCREMENT,
04.
name
varchar
(45)
NOT
NULL
,
05.
address
varchar
(45)
DEFAULT
NULL
,
06.
gender
char
(1)
DEFAULT
'M'
,
07.
dob datetime
DEFAULT
NULL
,
08.
email
varchar
(45)
DEFAULT
NULL
,
09.
mobile
varchar
(15)
DEFAULT
NULL
,
10.
phone
varchar
(15)
DEFAULT
NULL
,
11.
PRIMARY
KEY
(id)
12.
);
Step#2: Copy the SpringMVC, Hibernate and their dependent jars into WEB-INF/lib folder.
If you are using Maven you can mention the following dependencies.
001.
<
dependencies
>
002.
<
dependency
>
003.
<
groupId
>junit
groupId
>
004.
<
artifactId
>junit
artifactId
>
005.
<
version
>4.8.1
version
>
006.
<
type
>jar
type
>
007.
<
scope
>compile
scope
>
008.
dependency
>
009.
<
dependency
>
010.
<
groupId
>org.springframework
groupId
>
011.
<
artifactId
>spring-web
artifactId
>
012.
<
version
>3.0.5.RELEASE
version
>
013.
<
type
>jar
type
>
014.
<
scope
>compile
scope
>
015.
dependency
>
016.
<
dependency
>
017.
<
groupId
>org.springframework
groupId
>
018.
<
artifactId
>spring-core
artifactId
>
019.
<
version
>3.0.5.RELEASE
version
>
020.
<
type
>jar
type
>
021.
<
scope
>compile
scope
>
022.
<
exclusions
>
023.
<
exclusion
>
024.
<
artifactId
>commons-logging
artifactId
>
025.
<
groupId
>commons-logging
groupId
>
026.
exclusion
>
027.
exclusions
>
028.
dependency
>
029.
<
dependency
>
030.
<
groupId
>log4j
groupId
>
031.
<
artifactId
>log4j
artifactId
>
032.
<
version
>1.2.14
version
>
033.
<
type
>jar
type
>
034.
<
scope
>compile
scope
>
035.
dependency
>
036.
<
dependency
>
037.
<
groupId
>org.springframework
groupId
>
038.
<
artifactId
>spring-tx
artifactId
>
039.
<
version
>3.0.5.RELEASE
version
>
040.
<
type
>jar
type
>
041.
<
scope
>compile
scope
>
042.
dependency
>
043.
<
dependency
>
044.
<
groupId
>jstl
groupId
>
045.
<
artifactId
>jstl
artifactId
>
046.
<
version
>1.1.2
version
>
047.
<
type
>jar
type
>
048.
<
scope
>compile
scope
>
049.
dependency
>
050.
<
dependency
>
051.
<
groupId
>taglibs
groupId
>
052.
<
artifactId
>standard
artifactId
>
053.
<
version
>1.1.2
version
>
054.
<
type
>jar
type
>
055.
<
scope
>compile
scope
>
056.
dependency
>
057.
<
dependency
>
058.
<
groupId
>org.springframework
groupId
>
059.
<
artifactId
>spring-webmvc
artifactId
>
060.
<
version
>3.0.5.RELEASE
version
>
061.
<
type
>jar
type
>
062.
<
scope
>compile
scope
>
063.
dependency
>
064.
<
dependency
>
065.
<
groupId
>org.springframework
groupId
>
066.
<
artifactId
>spring-aop
artifactId
>
067.
<
version
>3.0.5.RELEASE
version
>
068.
<
type
>jar
type
>
069.
<
scope
>compile
scope
>
070.
dependency
>
071.
<
dependency
>
072.
<
groupId
>commons-digester
groupId
>
073.
<
artifactId
>commons-digester
artifactId
>
074.
<
version
>2.1
version
>
075.
<
type
>jar
type
>
076.
<
scope
>compile
scope
>
077.
dependency
>
078.
<
dependency
>
079.
<
groupId
>commons-collections
groupId
>
080.
<
artifactId
>commons-collections
artifactId
>
081.
<
version
>3.2.1
version
>
082.
<
type
>jar
type
>
083.
<
scope
>compile
scope
>
084.
dependency
>
085.
<
dependency
>
086.
<
groupId
>org.hibernate
groupId
>
087.
<
artifactId
>hibernate-core
artifactId
>
088.
<
version
>3.3.2.GA
version
>
089.
<
type
>jar
type
>
090.
<
scope
>compile
scope
>
091.
dependency
>
092.
<
dependency
>
093.
<
groupId
>javax.persistence
groupId
>
094.
<
artifactId
>persistence-api
artifactId
>
095.
<
version
>1.0
version
>
096.
<
type
>jar
type
>
097.
<
scope
>compile
scope
>
098.
dependency
>
099.
<
dependency
>
100.
<
groupId
>c3p0
groupId
>
101.
<
artifactId
>c3p0
artifactId
>
102.
<
version
>0.9.1.2
version
>
103.
<
type
>jar
type
>
104.
<
scope
>compile
scope
>
105.
dependency
>
106.
<
dependency
>
107.
<
groupId
>org.springframework
groupId
>
108.
<
artifactId
>spring-orm
artifactId
>
109.
<
version
>3.0.5.RELEASE
version
>
110.
<
type
>jar
type
>
111.
<
scope
>compile
scope
>
112.
dependency
>
113.
<
dependency
>
114.
<
groupId
>org.slf4j
groupId
>
115.
<
artifactId
>slf4j-api
artifactId
>
116.
<
version
>1.6.1
version
>
117.
<
type
>jar
type
>
118.
<
scope
>compile
scope
>
119.
dependency
>
120.
<
dependency
>
121.
<
groupId
>org.slf4j
groupId
>
122.
<
artifactId
>slf4j-log4j12
artifactId
>
123.
<
version
>1.6.1
version
>
124.
<
type
>jar
type
>
125.
<
scope
>compile
scope
>
126.
dependency
>
127.
<
dependency
>
128.
<
groupId
>cglib
groupId
>
129.
<
artifactId
>cglib-nodep
artifactId
>
130.
<
version
>2.2
version
>
131.
<
type
>jar
type
>
132.
<
scope
>compile
scope
>
133.
dependency
>
134.
<
dependency
>
135.
<
groupId
>org.hibernate
groupId
>
136.
<
artifactId
>hibernate-annotations
artifactId
>
137.
<
version
>3.4.0.GA
version
>
138.
<
type
>jar
type
>
139.
<
scope
>compile
scope
>
140.
dependency
>
141.
<
dependency
>
142.
<
groupId
>jboss
groupId
>
143.
<
artifactId
>javassist
artifactId
>
144.
<
version
>3.7.ga
version
>
145.
<
type
>jar
type
>
146.
<
scope
>compile
scope
>
147.
dependency
>
148.
<
dependency
>
149.
<
groupId
>mysql
groupId
>
150.
<
artifactId
>mysql-connector-java
artifactId
>
151.
<
version
>5.1.14
version
>
152.
<
type
>jar
type
>
153.
<
scope
>compile
scope
>
154.
dependency
>
155.
dependencies
>
Step#3: Configure SpringMVC
a) Configure DispatcherServlet in web.xml
01.
<
servlet
>
02.
<
servlet-name
>dispatcher
servlet-name
>
03.
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet
servlet-class
>
04.
<
load-on-startup
>1
load-on-startup
>
05.
servlet
>
06.
07.
<
servlet-mapping
>
08.
<
servlet-name
>dispatcher
servlet-name
>
09.
<
url-pattern
>*.do
url-pattern
>
10.
servlet-mapping
>
11.
12.
<
listener
>
13.
<
listener-class
>org.springframework.web.context.ContextLoaderListener
listener-class
>
14.
listener
>
15.
<
context-param
>
16.
<
param-name
>contextConfigLocation
param-name
>
17.
<
param-value
>classpath:applicationContext.xml
param-value
>
18.
context-param
>
b) Configure View Resolver in WEB-INF/dispatcher-servlet.xml
1.
<
bean
id
=
"viewResolver"
class
=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
2.
p:prefix
=
"/jsp/"
p:suffix
=
".jsp"
>
3.
bean
>
c) Configure Annotation support, PropertyPlaceHolderConfigurer, ResourceBundleMessageSource in WEB-INF/classes/applicationContext.xml
01.
<
context:annotation-config
>
context:annotation-config
>
02.
03.
<
context:component-scan
base-package
=
"com.sivalabs"
>
context:component-scan
>
04.
05.
<
mvc:annotation-driven
>
mvc:annotation-driven
>
06.
07.
<
context:property-placeholder
location
=
"classpath:config.properties"
>
context:property-placeholder
>
08.
09.
<
bean
id
=
"messageSource"
10.
class
=
"org.springframework.context.support.ResourceBundleMessageSource"
11.
p:basename
=
"Messages"
>
12.
bean
>
Step#4: Configure JDBC connection parameters and Hibernate properties in config.properties
01.
################### JDBC Configuration ##########################
02.
jdbc.driverClassName=com.mysql.jdbc.Driver
03.
jdbc.url=jdbc:mysql:
//localhost:3306/sivalabs
04.
jdbc.username=root
05.
jdbc.password=admin
06.
07.
################### Hibernate Configuration ##########################
08.
hibernate.dialect=org.hibernate.dialect.MySQLDialect
09.
hibernate.show_sql=
true
10.
#hibernate.hbm2ddl.auto=update
11.
hibernate.generate_statistics=
true
Step#5: Configure DataSource, SessionFactory, TransactionManagement support in WEB-INF/classes/applicationContext.xml
01.
"dataSource"
class
=
"org.springframework.jdbc.datasource.DriverManagerDataSource"
02.
p:driverClassName=
"${jdbc.driverClassName}"
03.
p:url=
"${jdbc.url}"
04.
p:username=
"${jdbc.username}"
05.
p:password=
"${jdbc.password}"
>
06.
07.
08.
"sessionFactory"
class
=
"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
>
09.
"dataSource"
ref=
"dataSource"
>
10.
"hibernateProperties"
>
11.
12.
"hibernate.dialect"
>${hibernate.dialect}
13.
"hibernate.show_sql"
>${hibernate.show_sql}
14.
15.
16.
"packagesToScan"
value=
"com.sivalabs"
>
17.
18.
19.
20.
"transactionManager"
21.
class
=
"org.springframework.orm.hibernate3.HibernateTransactionManager"
22.
p:sessionFactory-ref=
"sessionFactory"
>
23.
24.
25.
"transactionManager"
>
26.
Step#6: Configure the Labels, error messages in WEB-INF/classes/Messages.properties
1.
App.Title=SivaLabs
2.
typeMismatch.java.util.Date={
0
} is Invalid Date.
3.
dob=DOB
Step#7: Create the Entity class Contact.java
01.
package
com.sivalabs.contacts;
02.
03.
import
java.util.Date;
04.
05.
import
javax.persistence.Column;
06.
import
javax.persistence.Entity;
07.
import
javax.persistence.GeneratedValue;
08.
import
javax.persistence.GenerationType;
09.
import
javax.persistence.Id;
10.
import
javax.persistence.Table;
11.
12.
import
org.apache.commons.lang.builder.ToStringBuilder;
13.
14.
@Entity
15.
@Table
(name=
"CONTACTS"
)
16.
public
class
Contact
17.
{
18.
@Id
19.
@GeneratedValue
(strategy = GenerationType.AUTO)
20.
private
int
id;
21.
@Column
private
String name;
22.
@Column
private
String address;
23.
@Column
private
String gender;
24.
@Column
private
Date dob;
25.
@Column
private
String email;
26.
@Column
private
String mobile;
27.
@Column
private
String phone;
28.
29.
@Override
30.
public
String toString()
31.
{
32.
return
ToStringBuilder.reflectionToString(
this
);
33.
}
34.
//setters & getters
35.
}
Step#8: Create the ContactsDAO.java which performs CRUD operations on CONTACTS table.
01.
package
com.sivalabs.contacts;
02.
03.
import
java.util.List;
04.
05.
import
org.hibernate.Criteria;
06.
import
org.hibernate.SessionFactory;
07.
import
org.hibernate.criterion.Restrictions;
08.
import
org.springframework.beans.factory.annotation.Autowired;
09.
import
org.springframework.stereotype.Repository;
10.
import
org.springframework.transaction.annotation.Transactional;
11.
12.
@Repository
13.
@Transactional
14.
public
class
ContactsDAO
15.
{
16.
@Autowired
17.
private
SessionFactory sessionFactory;
18.
19.
public
Contact getById(
int
id)
20.
{
21.
return
(Contact) sessionFactory.getCurrentSession().get(Contact.
class
, id);
22.
}
23.
24.
@SuppressWarnings
(
"unchecked"
)
25.
public
List searchContacts(String name)
26.
{
27.
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.
class
);
28.
criteria.add(Restrictions.ilike(
"name"
, name+
"%"
));
29.
return
criteria.list();
30.
}
31.
32.
@SuppressWarnings
(
"unchecked"
)
33.
public
List getAllContacts()
34.
{
35.
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.
class
);
36.
return
criteria.list();
37.
}
38.
39.
public
int
save(Contact contact)
40.
{
41.
return
(Integer) sessionFactory.getCurrentSession().save(contact);
42.
}
43.
44.
public
void
update(Contact contact)
45.
{
46.
sessionFactory.getCurrentSession().merge(contact);
47.
}
48.
49.
public
void
delete(
int
id)
50.
{
51.
Contact c = getById(id);
52.
sessionFactory.getCurrentSession().delete(c);
53.
}
54.
}
Step#9: Create ContactFormValidator.java which performs the validations on saving/updating a contact.
01.
package
com.sivalabs.contacts;
02.
03.
import
org.springframework.stereotype.Component;
04.
import
org.springframework.validation.Errors;
05.
import
org.springframework.validation.ValidationUtils;
06.
import
org.springframework.validation.Validator;
07.
08.
@Component
(
"contactFormValidator"
)
09.
public
class
ContactFormValidator
implements
Validator
10.
{
11.
@SuppressWarnings
(
"unchecked"
)
12.
@Override
13.
public
boolean
supports(Class clazz)
14.
{
15.
return
Contact.
class
.isAssignableFrom(clazz);
16.
}
17.
18.
@Override
19.
public
void
validate(Object model, Errors errors)
20.
{
21.
ValidationUtils.rejectIfEmptyOrWhitespace(errors,
"name"
,
"required.name"
,
"Name is required."
);
22.
}
23.
}
Step#10: Create ContactsControllers.java which processes all the CRUD requests.
001.
package
com.sivalabs.contacts;
002.
003.
import
java.text.SimpleDateFormat;
004.
import
java.util.Date;
005.
import
java.util.List;
006.
007.
import
org.springframework.beans.factory.annotation.Autowired;
008.
import
org.springframework.beans.propertyeditors.CustomDateEditor;
009.
import
org.springframework.stereotype.Controller;
010.
import
org.springframework.validation.BindingResult;
011.
import
org.springframework.web.bind.WebDataBinder;
012.
import
org.springframework.web.bind.annotation.InitBinder;
013.
import
org.springframework.web.bind.annotation.ModelAttribute;
014.
import
org.springframework.web.bind.annotation.RequestMapping;
015.
import
org.springframework.web.bind.annotation.RequestMethod;
016.
import
org.springframework.web.bind.annotation.RequestParam;
017.
import
org.springframework.web.bind.support.SessionStatus;
018.
import
org.springframework.web.servlet.ModelAndView;
019.
020.
@Controller
021.
public
class
ContactsControllers
022.
{
023.
@Autowired
024.
private
ContactsDAO contactsDAO;
025.
026.
@Autowired
027.
private
ContactFormValidator validator;
028.
029.
@InitBinder
030.
public
void
initBinder(WebDataBinder binder)
031.
{
032.
SimpleDateFormat dateFormat =
new
SimpleDateFormat(
"dd-MM-yyyy"
);
033.
dateFormat.setLenient(
false
);
034.
binder.registerCustomEditor(Date.
class
,
new
CustomDateEditor(dateFormat,
true
));
035.
}
036.
037.
@RequestMapping
(
"/searchContacts"
)
038.
public
ModelAndView searchContacts(
@RequestParam
(required=
false
, defaultValue=
""
) String name)
039.
{
040.
ModelAndView mav =
new
ModelAndView(
"showContacts"
);
041.
List contacts = contactsDAO.searchContacts(name.trim());
042.
mav.addObject(
"SEARCH_CONTACTS_RESULTS_KEY"
, contacts);
043.
return
mav;
044.
}
045.
046.
@RequestMapping
(
"/viewAllContacts"
)
047.
public
ModelAndView getAllContacts()
048.
{
049.
ModelAndView mav =
new
ModelAndView(
"showContacts"
);
050.
List contacts = contactsDAO.getAllContacts();
051.
mav.addObject(
"SEARCH_CONTACTS_RESULTS_KEY"
, contacts);
052.
return
mav;
053.
}
054.
055.
@RequestMapping
(value=
"/saveContact"
, method=RequestMethod.GET)
056.
public
ModelAndView newuserForm()
057.
{
058.
ModelAndView mav =
new
ModelAndView(
"newContact"
);
059.
Contact contact =
new
Contact();
060.
mav.getModelMap().put(
"newContact"
, contact);
061.
return
mav;
062.
}
063.
064.
@RequestMapping
(value=
"/saveContact"
, method=RequestMethod.POST)
065.
public
String create(
@ModelAttribute
(
"newContact"
)Contact contact, BindingResult result, SessionStatus status)
066.
{
067.
validator.validate(contact, result);
068.
if
(result.hasErrors())
069.
{
070.
return
"newContact"
;
071.
}
072.
contactsDAO.save(contact);
073.
status.setComplete();
074.
return
"redirect:viewAllContacts.do"
;
075.
}
076.
077.
@RequestMapping
(value=
"/updateContact"
, method=RequestMethod.GET)
078.
public
ModelAndView edit(
@RequestParam
(
"id"
)Integer id)
079.
{
080.
ModelAndView mav =
new
ModelAndView(
"editContact"
);
081.
Contact contact = contactsDAO.getById(id);
082.
mav.addObject(
"editContact"
, contact);
083.
return
mav;
084.
}
085.
086.
@RequestMapping
(value=
"/updateContact"
, method=RequestMethod.POST)
087.
public
String update(
@ModelAttribute
(
"editContact"
) Contact contact, BindingResult result, SessionStatus status)
088.
{
089.
validator.validate(contact, result);
090.
if
(result.hasErrors()) {
091.
return
"editContact"
;
092.
}
093.
contactsDAO.update(contact);
094.
status.setComplete();
095.
return
"redirect:viewAllContacts.do"
;
096.
}
097.
098.
@RequestMapping
(
"deleteContact"
)
099.
public
ModelAndView delete(
@RequestParam
(
"id"
)Integer id)
100.
{
101.
ModelAndView mav =
new
ModelAndView(
"redirect:viewAllContacts.do"
);
102.
contactsDAO.delete(id);
103.
return
mav;
104.
}
105.
}
Step#11: Instead of writing the JSTL tag library declerations in all the JSPs, declare them in one JSP and include that JSP in other JSPs.
taglib_includes.jsp
1.
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
2.
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
3.
4.
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
5.
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
Step#12: Create the JSPs.
a)showContacts.jsp
01.
<%@include file="taglib_includes.jsp" %>
02.
03.
<
html
>
04.
<
head
>
05.
06.
<
title
><
spring:message
code
=
"App.Title"
>
spring:message
>
title
>
07.
<
script
type
=
"text/javascript"
src
=
"js/contacts.js"
>
script
>
08.
head
>
09.
<
body
style
=
"font-family: Arial; font-size:smaller;"
>
10.
<
center
>
11.
<
form
action
=
"searchContacts.do"
method
=
"post"
>
12.
<
table
style
=
"border-collapse: collapse;"
border
=
"0"
bordercolor
=
"#006699"
width
=
"500"
>
13.
<
tr
>
14.
<
td
>Enter Contact Name
td
>
15.
<
td
><
input
type
=
"text"
name
=
"name"
/>
16.
<
input
type
=
"submit"
value
=
"Search"
/>
17.
<
input
type
=
"button"
value
=
"New Contact"
onclick
=
"javascript:go('saveContact.do');"
/>
18.
td
>
tr
>
19.
table
>
20.
form
>
21.
22.
<
table
style
=
"border-collapse: collapse;"
border
=
"1"
bordercolor
=
"#006699"
width
=
"500"
>
23.
<
tr
bgcolor
=
"lightblue"
>
24.
<
th
>Id
th
>
25.
<
th
>Name
th
>
26.
<
th
>Address
th
>
27.
<
th
>Mobile
th
>
28.
<
th
>
th
>
29.
tr
>
30.
<
c:if
test
=
"${empty SEARCH_CONTACTS_RESULTS_KEY}"
>
31.
<
tr
>
32.
<
td
colspan
=
"4"
>No Results found
td
>
33.
tr
>
34.
c:if
>
35.
<
c:if
test
=
"${! empty SEARCH_CONTACTS_RESULTS_KEY}"
>
36.
<
c:forEach
var
=
"contact"
items
=
"${SEARCH_CONTACTS_RESULTS_KEY}"
>
37.
<
tr
>
38.
<
td
><
c:out
value
=
"${contact.id}"
>
c:out
>
td
>
39.
<
td
><
c:out
value
=
"${contact.name}"
>
c:out
>
td
>
40.
<
td
><
c:out
value
=
"${contact.address}"
>
c:out
>
td
>
41.
<
td
><
c:out
value
=
"${contact.mobile}"
>
c:out
>
td
>
42.
<
td
>
43.
<
a
href
=
"updateContact.do?id=${contact.id}"
>Edit
a
>
44.
<
a
href
=
"javascript:deleteContact('deleteContact.do?id=${contact.id}');"
>Delete
a
>
45.
td
>
46.
tr
>
47.
c:forEach
>
48.
c:if
>
49.
table
>
50.
center
>
51.
52.
body
>
53.
html
>
b)newContact.jsp
01.
<%@include file="taglib_includes.jsp" %>
02.
03.
<
html
>
04.
<
head
>
05.
<
script
type
=
"text/javascript"
src
=
"js/contacts.js"
>
script
>
06.
<
title
><
spring:message
code
=
"App.Title"
>
spring:message
>
title
>
07.
head
>
08.
<
body
style
=
"font-family: Arial; font-size:smaller;"
>
09.
10.
<
table
bgcolor
=
"lightblue"
width
=
"750"
height
=
"500"
align
=
"center"
style
=
"border-collapse: collapse;"
border
=
"1"
bordercolor
=
"#006699"
>
11.
<
tr
>
12.
<
td
align
=
"center"
><
h3
>Edit Contact Form
h3
>
td
>
13.
tr
>
14.
<
tr
valign
=
"top"
align
=
"center"
>