To learn any web framework starting with a HelloWorld application is a good idea. Once we get familiarity with the framework configuration it would be better to do a CRUD(Create,Read,Update,Delete) application which covers various aspects of a web framework like Validations, 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 ContactsManagements where you can view or search contacts, create new contacts, edit or delete existing contacts.
Step#1: Create the CONTACTS Table
CREATE TABLE CONTACTS
(
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
address varchar(45) DEFAULT NULL,
gender char(1) DEFAULT 'M',
dob datetime DEFAULT NULL,
email varchar(45) DEFAULT NULL,
mobile varchar(15) DEFAULT NULL,
phone varchar(15) DEFAULT NULL,
PRIMARY KEY (id)
);
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.
junit
junit
4.8.1
jar
compile
org.springframework
spring-web
3.0.5.RELEASE
jar
compile
org.springframework
spring-core
3.0.5.RELEASE
jar
compile
commons-logging
commons-logging
log4j
log4j
1.2.14
jar
compile
org.springframework
spring-tx
3.0.5.RELEASE
jar
compile
jstl
jstl
1.1.2
jar
compile
taglibs
standard
1.1.2
jar
compile
org.springframework
spring-webmvc
3.0.5.RELEASE
jar
compile
org.springframework
spring-aop
3.0.5.RELEASE
jar
compile
commons-digester
commons-digester
2.1
jar
compile
commons-collections
commons-collections
3.2.1
jar
compile
org.hibernate
hibernate-core
3.3.2.GA
jar
compile
javax.persistence
persistence-api
1.0
jar
compile
c3p0
c3p0
0.9.1.2
jar
compile
org.springframework
spring-orm
3.0.5.RELEASE
jar
compile
org.slf4j
slf4j-api
1.6.1
jar
compile
org.slf4j
slf4j-log4j12
1.6.1
jar
compile
cglib
cglib-nodep
2.2
jar
compile
org.hibernate
hibernate-annotations
3.4.0.GA
jar
compile
jboss
javassist
3.7.ga
jar
compile
mysql
mysql-connector-java
5.1.14
jar
compile
Step#3: Configure SpringMVC
a) Configure DispatcherServlet in web.xml
dispatcher
org.springframework.web.servlet.DispatcherServlet
1
dispatcher
*.do
org.springframework.web.context.ContextLoaderListener
contextConfigLocationclasspath:applicationContext.xml
b) Configure View Resolver in WEB-INF/dispatcher-servlet.xml
c) Configure Annotation support, PropertyPlaceHolderConfigurer, ResourceBundleMessageSource in WEB-INF/classes/applicationContext.xml
Step#4: Configure JDBC connection parameters and Hibernate properties in config.properties
################### JDBC Configuration ##########################
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sivalabs
jdbc.username=root
jdbc.password=admin
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
#hibernate.hbm2ddl.auto=update
hibernate.generate_statistics=true
Step#5: Configure DataSource, SessionFactory, TransactionManagement support in WEB-INF/classes/applicationContext.xml
${hibernate.dialect}
${hibernate.show_sql}
Step#6: Configure the Labels, error messages in WEB-INF/classes/Messages.properties
App.Title=SivaLabs
typeMismatch.java.util.Date={0} is Invalid Date.
dob=DOB
Step#7: Create the Entity class Contact.java
package com.sivalabs.contacts;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.commons.lang.builder.ToStringBuilder;
@Entity
@Table(name="CONTACTS")
public class Contact
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column private String name;
@Column private String address;
@Column private String gender;
@Column private Date dob;
@Column private String email;
@Column private String mobile;
@Column private String phone;
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
//setters & getters
}
Step#8: Create the ContactsDAO.java which performs CRUD operations on CONTACTS table.
package com.sivalabs.contacts;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public class ContactsDAO
{
@Autowired
private SessionFactory sessionFactory;
public Contact getById(int id)
{
return (Contact) sessionFactory.getCurrentSession().get(Contact.class, id);
}
@SuppressWarnings("unchecked")
public List<Contact> searchContacts(String name)
{
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.class);
criteria.add(Restrictions.ilike("name", name+"%"));
return criteria.list();
}
@SuppressWarnings("unchecked")
public List<Contact> getAllContacts()
{
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.class);
return criteria.list();
}
public int save(Contact contact)
{
return (Integer) sessionFactory.getCurrentSession().save(contact);
}
public void update(Contact contact)
{
sessionFactory.getCurrentSession().merge(contact);
}
public void delete(int id)
{
Contact c = getById(id);
sessionFactory.getCurrentSession().delete(c);
}
}
Step#9: Create ContactFormValidator.java which performs the validations on saving/updating a contact.
package com.sivalabs.contacts;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
@Component("contactFormValidator")
public class ContactFormValidator implements Validator
{
@SuppressWarnings("unchecked")
@Override
public boolean supports(Class clazz)
{
return Contact.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object model, Errors errors)
{
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name","required.name", "Name is required.");
}
}
Step#10: Create ContactsControllers.java which processes all the CRUD requests.
package com.sivalabs.contacts;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ContactsControllers
{
@Autowired
private ContactsDAO contactsDAO;
@Autowired
private ContactFormValidator validator;
@InitBinder
public void initBinder(WebDataBinder binder)
{
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
@RequestMapping("/searchContacts")
public ModelAndView searchContacts(@RequestParam(required= false, defaultValue="") String name)
{
ModelAndView mav = new ModelAndView("showContacts");
List<Contact> contacts = contactsDAO.searchContacts(name.trim());
mav.addObject("SEARCH_CONTACTS_RESULTS_KEY", contacts);
return mav;
}
@RequestMapping("/viewAllContacts")
public ModelAndView getAllContacts()
{
ModelAndView mav = new ModelAndView("showContacts");
List<Contact> contacts = contactsDAO.getAllContacts();
mav.addObject("SEARCH_CONTACTS_RESULTS_KEY", contacts);
return mav;
}
@RequestMapping(value="/saveContact", method=RequestMethod.GET)
public ModelAndView newuserForm()
{
ModelAndView mav = new ModelAndView("newContact");
Contact contact = new Contact();
mav.getModelMap().put("newContact", contact);
return mav;
}
@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contact contact, BindingResult result, SessionStatus status)
{
validator.validate(contact, result);
if (result.hasErrors())
{
return "newContact";
}
contactsDAO.save(contact);
status.setComplete();
return "redirect:viewAllContacts.do";
}
@RequestMapping(value="/updateContact", method=RequestMethod.GET)
public ModelAndView edit(@RequestParam("id")Integer id)
{
ModelAndView mav = new ModelAndView("editContact");
Contact contact = contactsDAO.getById(id);
mav.addObject("editContact", contact);
return mav;
}
@RequestMapping(value="/updateContact", method=RequestMethod.POST)
public String update(@ModelAttribute("editContact") Contact contact, BindingResult result, SessionStatus status)
{
validator.validate(contact, result);
if (result.hasErrors()) {
return "editContact";
}
contactsDAO.update(contact);
status.setComplete();
return "redirect:viewAllContacts.do";
}
@RequestMapping("deleteContact")
public ModelAndView delete(@RequestParam("id")Integer id)
{
ModelAndView mav = new ModelAndView("redirect:viewAllContacts.do");
contactsDAO.delete(id);
return mav;
}
}
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
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
Step#12: Create the JSPs.
a)showContacts.jsp
<%@include file="taglib_includes.jsp" %>
<html>
<head>
<title> </title>
</head>
<body style="font-family: Arial; font-size:smaller;">
| Id | Name | Address | Mobile | |
| No Results found |
| | | |
Edit
Delete |
</body>
</html>
b)newContact.jsp
<%@include file="taglib_includes.jsp" %>
<html>
<head>
<title> </title>
</head>
<body style="font-family: Arial; font-size:smaller;">
</body>
</html>
a)editContact.jsp
<%@include file="taglib_includes.jsp" %>
<html>
<head>
<title> </title>
</head>
<body style="font-family: Arial; font-size:smaller;">
</body>
</html>
Step#13: Write the javascript file js/contacts.js containing the utility methods
function go(url)
{
window.location = url;
}
function deleteContact(url)
{
var isOK = confirm("Are you sure to delete?");
if(isOK)
{
go(url);
}
}
Step#14: The welcome file index.jsp
<%
response.sendRedirect("viewAllContacts.do");
%>
Step#15: Start the server and point your browser URL to http://localhost:8080/SpringMVCHibernate
You can download the source code at
SpringMVCHibernate.zip