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 Spring MVC3, 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
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, |
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.
003 | <groupid>junit</groupid> |
004 | <artifactid>junit</artifactid> |
005 | <version>4.8.1</version> |
007 | <scope>compile</scope> |
010 | <groupid>org.springframework</groupid> |
011 | <artifactid>spring-web</artifactid> |
012 | <version>3.0.5.RELEASE</version> |
014 | <scope>compile</scope> |
017 | <groupid>org.springframework</groupid> |
018 | <artifactid>spring-core</artifactid> |
019 | <version>3.0.5.RELEASE</version> |
021 | <scope>compile</scope> |
024 | <artifactid>commons-logging</artifactid> |
025 | <groupid>commons-logging</groupid> |
030 | <groupid>log4j</groupid> |
031 | <artifactid>log4j</artifactid> |
032 | <version>1.2.14</version> |
034 | <scope>compile</scope> |
037 | <groupid>org.springframework</groupid> |
038 | <artifactid>spring-tx</artifactid> |
039 | <version>3.0.5.RELEASE</version> |
041 | <scope>compile</scope> |
044 | <groupid>jstl</groupid> |
045 | <artifactid>jstl</artifactid> |
046 | <version>1.1.2</version> |
048 | <scope>compile</scope> |
051 | <groupid>taglibs</groupid> |
052 | <artifactid>standard</artifactid> |
053 | <version>1.1.2</version> |
055 | <scope>compile</scope> |
058 | <groupid>org.springframework</groupid> |
059 | <artifactid>spring-webmvc</artifactid> |
060 | <version>3.0.5.RELEASE</version> |
062 | <scope>compile</scope> |
065 | <groupid>org.springframework</groupid> |
066 | <artifactid>spring-aop</artifactid> |
067 | <version>3.0.5.RELEASE</version> |
069 | <scope>compile</scope> |
072 | <groupid>commons-digester</groupid> |
073 | <artifactid>commons-digester</artifactid> |
074 | <version>2.1</version> |
076 | <scope>compile</scope> |
079 | <groupid>commons-collections</groupid> |
080 | <artifactid>commons-collections</artifactid> |
081 | <version>3.2.1</version> |
083 | <scope>compile</scope> |
086 | <groupid>org.hibernate</groupid> |
087 | <artifactid>hibernate-core</artifactid> |
088 | <version>3.3.2.GA</version> |
090 | <scope>compile</scope> |
093 | <groupid>javax.persistence</groupid> |
094 | <artifactid>persistence-api</artifactid> |
095 | <version>1.0</version> |
097 | <scope>compile</scope> |
100 | <groupid>c3p0</groupid> |
101 | <artifactid>c3p0</artifactid> |
102 | <version>0.9.1.2</version> |
104 | <scope>compile</scope> |
107 | <groupid>org.springframework</groupid> |
108 | <artifactid>spring-orm</artifactid> |
109 | <version>3.0.5.RELEASE</version> |
111 | <scope>compile</scope> |
114 | <groupid>org.slf4j</groupid> |
115 | <artifactid>slf4j-api</artifactid> |
116 | <version>1.6.1</version> |
118 | <scope>compile</scope> |
121 | <groupid>org.slf4j</groupid> |
122 | <artifactid>slf4j-log4j12</artifactid> |
123 | <version>1.6.1</version> |
125 | <scope>compile</scope> |
128 | <groupid>cglib</groupid> |
129 | <artifactid>cglib-nodep</artifactid> |
130 | <version>2.2</version> |
132 | <scope>compile</scope> |
135 | <groupid>org.hibernate</groupid> |
136 | <artifactid>hibernate-annotations</artifactid> |
137 | <version>3.4.0.GA</version> |
139 | <scope>compile</scope> |
142 | <groupid>jboss</groupid> |
143 | <artifactid>javassist</artifactid> |
144 | <version>3.7.ga</version> |
146 | <scope>compile</scope> |
149 | <groupid>mysql</groupid> |
150 | <artifactid>mysql-connector-java</artifactid> |
151 | <version>5.1.14</version> |
153 | <scope>compile</scope> |
Step#3: Configure SpringMVC
a) Configure DispatcherServlet in web.xml
02 | <servlet-name>dispatcher</servlet-name> |
03 | <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> |
04 | <load-on-startup>1</load-on-startup> |
08 | <servlet-name>dispatcher</servlet-name> |
09 | <url-pattern>*.do</url-pattern> |
13 | <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> |
16 | <param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value> |
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"> |
c)
Configure Annotation support, PropertyPlaceHolderConfigurer,
ResourceBundleMessageSource in WEB-INF/classes/applicationContext.xml
01 | <context:annotation-config></context:annotation-config> |
03 | <context:component-scan base-package="com.sivalabs"></context:component-scan> |
05 | <mvc:annotation-driven> </mvc:annotation-driven> |
07 | <context:property-placeholder location="classpath:config.properties"></context:property-placeholder> |
09 | <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" |
10 | p:basename="Messages"></bean> |
Step#4: Configure JDBC connection parameters and Hibernate properties in config.properties
02 | jdbc.driverClassName=com.mysql.jdbc.Driver |
08 | hibernate.dialect=org.hibernate.dialect.MySQLDialect |
09 | hibernate.show_sql=true |
11 | hibernate.generate_statistics=true |
Step#5: Configure DataSource, SessionFactory, TransactionManagement support in WEB-INF/classes/applicationContext.xml
01 | <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" |
02 | p:driverclassname="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"> |
05 | <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> |
06 | <property name="dataSource" ref="dataSource"></property> |
07 | <property name="hibernateProperties"> |
09 | <prop key="hibernate.dialect">${hibernate.dialect}</prop> |
10 | <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> |
13 | <property name="packagesToScan" value="com.sivalabs"></property> |
17 | <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" |
18 | p:sessionfactory-ref="sessionFactory"> |
21 | <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven> |
Step#6: Configure the Labels, error messages in WEB-INF/classes/Messages.properties
2 | typeMismatch.java.util.Date={0} is Invalid Date. |
Step#7: Create the Entity class Contact.java
01 | package com.sivalabs.contacts; |
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; |
12 | import org.apache.commons.lang.builder.ToStringBuilder; |
15 | @Table(name="CONTACTS") |
19 | @GeneratedValue(strategy = GenerationType.AUTO) |
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; |
30 | public String toString() |
32 | return ToStringBuilder.reflectionToString(this); |
Step#8: Create the ContactsDAO.java which performs CRUD operations on CONTACTS table.
01 | package com.sivalabs.contacts; |
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; |
14 | public class ContactsDAO |
17 | private SessionFactory sessionFactory; |
19 | public Contact getById(int id) |
21 | return (Contact) sessionFactory.getCurrentSession().get(Contact.class, id); |
24 | @SuppressWarnings("unchecked") |
25 | public List searchContacts(String name) |
27 | Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.class); |
28 | criteria.add(Restrictions.ilike("name", name+"%")); |
29 | return criteria.list(); |
32 | @SuppressWarnings("unchecked") |
33 | public List getAllContacts() |
35 | Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Contact.class); |
36 | return criteria.list(); |
39 | public int save(Contact contact) |
41 | return (Integer) sessionFactory.getCurrentSession().save(contact); |
44 | public void update(Contact contact) |
46 | sessionFactory.getCurrentSession().merge(contact); |
49 | public void delete(int id) |
51 | Contact c = getById(id); |
52 | sessionFactory.getCurrentSession().delete(c); |
Step#9: Create ContactFormValidator.java which performs the validations on saving/updating a contact.
01 | package com.sivalabs.contacts; |
03 | import org.springframework.stereotype.Component; |
04 | import org.springframework.validation.Errors; |
05 | import org.springframework.validation.ValidationUtils; |
06 | import org.springframework.validation.Validator; |
08 | @Component("contactFormValidator") |
09 | public class ContactFormValidator implements Validator |
11 | @SuppressWarnings("unchecked") |
13 | public boolean supports(Class clazz) |
15 | return Contact.class.isAssignableFrom(clazz); |
19 | public void validate(Object model, Errors errors) |
21 | ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name","required.name", "Name is required."); |
Step#10: Create ContactsControllers.java which processes all the CRUD requests.
001 | package com.sivalabs.contacts; |
003 | import java.text.SimpleDateFormat; |
004 | import java.util.Date; |
005 | import java.util.List; |
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; |
021 | public class ContactsControllers |
024 | private ContactsDAO contactsDAO; |
027 | private ContactFormValidator validator; |
030 | public void initBinder(WebDataBinder binder) |
032 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); |
033 | dateFormat.setLenient(false); |
034 | binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); |
037 | @RequestMapping("/searchContacts") |
038 | public ModelAndView searchContacts(@RequestParam(required= false, defaultValue="") String name) |
040 | ModelAndView mav = new ModelAndView("showContacts"); |
041 | List contacts = contactsDAO.searchContacts(name.trim()); |
042 | mav.addObject("SEARCH_CONTACTS_RESULTS_KEY", contacts); |
046 | @RequestMapping("/viewAllContacts") |
047 | public ModelAndView getAllContacts() |
049 | ModelAndView mav = new ModelAndView("showContacts"); |
050 | List contacts = contactsDAO.getAllContacts(); |
051 | mav.addObject("SEARCH_CONTACTS_RESULTS_KEY", contacts); |
055 | @RequestMapping(value="/saveContact", method=RequestMethod.GET) |
056 | public ModelAndView newuserForm() |
058 | ModelAndView mav = new ModelAndView("newContact"); |
059 | Contact contact = new Contact(); |
060 | mav.getModelMap().put("newContact", contact); |
064 | @RequestMapping(value="/saveContact", method=RequestMethod.POST) |
065 | public String create(@ModelAttribute("newContact")Contact contact, BindingResult result, SessionStatus status) |
067 | validator.validate(contact, result); |
068 | if (result.hasErrors()) |
072 | contactsDAO.save(contact); |
073 | status.setComplete(); |
074 | return "redirect:viewAllContacts.do"; |
077 | @RequestMapping(value="/updateContact", method=RequestMethod.GET) |
078 | public ModelAndView edit(@RequestParam("id")Integer id) |
080 | ModelAndView mav = new ModelAndView("editContact"); |
081 | Contact contact = contactsDAO.getById(id); |
082 | mav.addObject("editContact", contact); |
086 | @RequestMapping(value="/updateContact", method=RequestMethod.POST) |
087 | public String update(@ModelAttribute("editContact") Contact contact, BindingResult result, SessionStatus status) |
089 | validator.validate(contact, result); |
090 | if (result.hasErrors()) { |
091 | return "editContact"; |
093 | contactsDAO.update(contact); |
094 | status.setComplete(); |
095 | return "redirect:viewAllContacts.do"; |
098 | @RequestMapping("deleteContact") |
099 | public ModelAndView delete(@RequestParam("id")Integer id) |
101 | ModelAndView mav = new ModelAndView("redirect:viewAllContacts.do"); |
102 | contactsDAO.delete(id); |
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
Step#12: Create the JSPs.
a)showContacts.jsp
01 | <%@include file="taglib_includes.jsp" %> |
06 | <title><spring:message code="App.Title"></spring:message> </title> |
07 | <script type="text/javascript" src="js/contacts.js"></script> |
09 | <body style="font-family: Arial; font-size:smaller;"> |
11 | <form action="searchContacts.do" method="post"><table style="border-collapse: collapse;" width="500" border="0" bordercolor="#006699"><tbody><tr> <td>Enter Contact Name</td> <td><input name="name" type="text"> |
13 | <input value="Search" type="submit"> |
15 | <input value="New Contact" onclick="javascript:go('saveContact.do');" type="button"> |
18 | </tbody></table></form><c:if test="${empty SEARCH_CONTACTS_RESULTS_KEY}"> |
19 | </c:if><c:if test="${! empty SEARCH_CONTACTS_RESULTS_KEY}"> <c:foreach var="contact" items="${SEARCH_CONTACTS_RESULTS_KEY}"> |
20 | </c:foreach></c:if><table style="border-collapse: collapse;" width="500" border="1" bordercolor="#006699"><tbody><tr bgcolor="lightblue"> <th>Id</th> <th>Name</th> <th>Address</th> <th>Mobile</th> <th></th> </tr> |
21 | <tr> <td colspan="4">No Results found</td> </tr> |
22 | <tr> <td><c:out value="${contact.id}"></c:out></td> <td><c:out value="${contact.name}"></c:out></td> <td><c:out value="${contact.address}"></c:out> </td> <td><c:out value="${contact.mobile}"></c:out></td> <td> |
24 | <a href="updateContact.do?id=$%7Bcontact.id%7D">Edit</a> |
26 | <a href="javascript:deleteContact('deleteContact.do?id=${contact.id}');">Delete</a> |
29 | </tbody></table></center> |
b)newContact.jsp
01 | <%@include file="taglib_includes.jsp" %> |
05 | <script type="text/javascript" src="js/contacts.js"></script> |
06 | <title><spring:message code="App.Title"></spring:message> </title> |
08 | <body style="font-family: Arial; font-size:smaller;"> |
10 | <table style="border-collapse: collapse;" width="750" align="center" bgcolor="lightblue" border="1" bordercolor="#006699" height="500"><tbody><tr> <td align="center"><h3>Edit Contact Form</h3></td> </tr> |
11 | <tr valign="top" align="center"> <td align="center"> |
13 | <form:form action="saveContact.do" method="post" commandname="newContact"><table style="border-collapse: collapse;" width="500" border="0" bordercolor="#006699" cellpadding="2" cellspacing="2"><tbody><tr> <td width="100" align="right">Name</td> <td width="150"> |
15 | <form:input path="name"></form:input></td> <td align="left"> |
17 | <form:errors path="name" cssstyle="color:red"></form:errors></td> </tr> |
18 | <tr> <td width="100" align="right">DOB</td> <td><form:input path="dob"></form:input></td> <td align="left"><form:errors path="dob" cssstyle="color:red"></form:errors></td> </tr> |
19 | <tr> <td width="100" align="right">Gender</td> <td> |
21 | <form:select path="gender"><form:option value="M" label="Male"><form:option value="F" label="Female"></form:option></form:option></form:select></td> <td> |
24 | <tr> <td width="100" align="right">Address</td> <td><form:input path="address"></form:input></td> <td align="left"> |
26 | <form:errors path="address" cssstyle="color:red"></form:errors></td> </tr> |
27 | <tr> <td width="100" align="right">Email</td> <td><form:input path="email"></form:input></td> <td align="left"><form:errors path="email" cssstyle="color:red"></form:errors></td> </tr> |
28 | <tr> <td width="100" align="right">Mobile</td> <td><form:input path="mobile"></form:input></td> <td align="left"> |
30 | <form:errors path="mobile" cssstyle="color:red"></form:errors></td> </tr> |
31 | <tr> <td colspan="3" align="center"> |
33 | <input name="" value="Save" type="submit"> |
37 | <input name="" value="Reset" type="reset"> |
41 | <input value="Back" onclick="javascript:go('viewAllContacts.do');" type="button"> |
44 | </tbody></table></form:form></td> </tr> |
45 | </tbody></table></body> |
a)editContact.jsp
01 | <%@include file="taglib_includes.jsp" %> |
05 | <script type="text/javascript" src="js/contacts.js"></script> |
06 | <title><spring:message code="App.Title"></spring:message> </title> |
08 | <body style="font-family: Arial; font-size:smaller;"> |
10 | <table style="border-collapse: collapse;" width="750" align="center" bgcolor="lightblue" border="1" bordercolor="#006699" height="500"><tbody><tr> <td align="center"><h3>Edit Contact Form</h3></td> </tr> |
11 | <tr valign="top" align="center"> <td align="center"> |
13 | <form:form action="updateContact.do" method="post" commandname="editContact"><table style="border-collapse: collapse;" width="500" border="0" bordercolor="#006699" cellpadding="2" cellspacing="2"><tbody><tr> <td width="100" align="right">Id</td> <td width="150"> |
15 | <form:input path="id" readonly="true"></form:input></td> <td align="left"> |
17 | <form:errors path="id" cssstyle="color:red"></form:errors></td> </tr> |
18 | <tr> <td width="100" align="right">Name</td> <td> |
20 | <form:input path="name"></form:input></td> <td align="left"> |
22 | <form:errors path="name" cssstyle="color:red"></form:errors></td> </tr> |
23 | <tr> <td width="100" align="right">DOB</td> <td><form:input path="dob"></form:input></td> <td align="left"><form:errors path="dob" cssstyle="color:red"></form:errors></td> </tr> |
24 | <tr> <td width="100" align="right">Gender</td> <td> |
26 | <form:select path="gender"><form:option value="M" label="Male"><form:option value="F" label="Female"></form:option></form:option></form:select></td> <td> |
29 | <tr> <td width="100" align="right">Address</td> <td><form:input path="address"></form:input></td> <td align="left"> |
31 | <form:errors path="address" cssstyle="color:red"></form:errors></td> </tr> |
32 | <tr> <td width="100" align="right">Email</td> <td><form:input path="email"></form:input></td> <td align="left"><form:errors path="email" cssstyle="color:red"></form:errors></td> </tr> |
33 | <tr> <td width="100" align="right">Mobile</td> <td><form:input path="mobile"></form:input></td> <td align="left"> |
35 | <form:errors path="mobile" cssstyle="color:red"></form:errors></td> </tr> |
36 | <tr valign="bottom"> <td colspan="3" align="center"> |
38 | <input value="Delete" onclick="javascript:deleteContact('deleteContact.do?id=${editContact.id}');" type="button"> |
42 | <input name="" value="Save" type="submit"> |
46 | <input value="Back" onclick="javascript:go('viewAllContacts.do');" type="button"> |
49 | </tbody></table></form:form></td> </tr> |
50 | </tbody></table></body> |
Step#13: Write the javascript file js/contacts.js containing the utility methods
03 | window.location = url; |
06 | function deleteContact(url) |
08 | var isOK = confirm("Are you sure to delete?"); |
Step#14: The welcome file index.jsp
2 | response.sendRedirect("viewAllContacts.do"); |
Step#15: Start the server and point your browser URL to
http://localhost:8080/SpringMVCHibernate
No comments:
Post a Comment