This example builds on the last post, Spring MVC 4 - Java Config, where Spring Java configuration files replaced the standard Spring MVC template XML files created by STS in Eclipse. In addition, this code shows an end-to-end example of:
MySQL -> Hibernate -> Spring MVC -> JSP
A link to the code on GitHub is provided at the bottom of this post. Here is a summary of the steps to complete the end to end use case:
1. Create a table in your database using the SQL below. This SQL creates a simple table with three columns. This table will hold our trade strategies. The type would contain an option trade type, and the name would contain a specific sub type. For example, type could be "iron condor", and name could be "hedged high prob".MySQL -> Hibernate -> Spring MVC -> JSP
A link to the code on GitHub is provided at the bottom of this post. Here is a summary of the steps to complete the end to end use case:
CREATE TABLE `strategy` ( `ID` INT(6) UNSIGNED NOT NULL AUTO_INCREMENT, `TYPE` VARCHAR(20) NOT NULL, `NAME` VARCHAR(20) NOT NULL, PRIMARY KEY (`ID`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=8;
2. Create the Spring database configuration file to configure the Spring and Hibernate connectivity to our database where we created the strategy table.
package com.dtr.oas.config; import java.util.Properties; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @ComponentScan("com.dtr.oas") @PropertySource("classpath:database.properties") public class DatabaseConfig { private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver"; private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password"; private static final String PROPERTY_NAME_DATABASE_URL = "db.url"; private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username"; private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect"; private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan"; @Resource private Environment env; @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)); dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)); dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)); dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); return dataSource; } private Properties hibProperties() { Properties properties = new Properties(); properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)); properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL)); return properties; } @Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; } @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN)); sessionFactoryBean.setHibernateProperties(hibProperties()); return sessionFactoryBean; } }
3. Create the properties file used by the database configuration java file. This file will contain the details about our specific database. This file is located in the resources directory under main (not the one in webapp).
#DB properties: db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://192.168.0.100:3306/oas db.username=root db.password=password #Hibernate Configuration: hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect hibernate.show_sql=true entitymanager.packages.to.scan=com.dtr.oas.model
4. Update the Initializer.java to load the new database configuration file. The only change to this code was the addition of the DatabaseConfig.class entry in the getRootConfigClasses method:
package com.dtr.oas.config; import org.springframework.core.annotation.Order; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import com.dtr.oas.config.DatabaseConfig; @Order(1) public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { DatabaseConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebAppConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
5. We now create the standard model, DAO, and service layers. The model/entity class is first:
package com.dtr.oas.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="strategy") public class Strategy { @Id @GeneratedValue private Integer id; private String type; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
6. The DAO layer has an interface and an implementation:
package com.dtr.oas.dao; import java.util.List; import com.dtr.oas.model.Strategy; public interface StrategyDAO { public void addStrategy(Strategy strategy); public Strategy getStrategy(int id); public void updateStrategy(Strategy strategy); public void deleteStrategy(int id); public List<Strategy> getStrategies(); }
package com.dtr.oas.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.dtr.oas.model.Strategy; @Repository public class StrategyDAOImpl implements StrategyDAO { @Autowired private SessionFactory sessionFactory; private Session getCurrentSession() { return sessionFactory.getCurrentSession(); } public void addStrategy(Strategy strategy) { getCurrentSession().save(strategy); } public void updateStrategy(Strategy strategy) { Strategy strategyToUpdate = getStrategy(strategy.getId()); strategyToUpdate.setName(strategy.getName()); strategyToUpdate.setType(strategy.getType()); getCurrentSession().update(strategyToUpdate); } public Strategy getStrategy(int id) { Strategy strategy = (Strategy) getCurrentSession().get(Strategy.class, id); return strategy; } public void deleteStrategy(int id) { Strategy strategy = getStrategy(id); if (strategy != null) getCurrentSession().delete(strategy); } @SuppressWarnings("unchecked") public List<Strategy> getStrategies() { return getCurrentSession().createQuery("from Strategy").list(); } }
7. The service layer contains an interface and an implementation:
package com.dtr.oas.service; import java.util.List; import com.dtr.oas.model.Strategy; public interface StrategyService { public void addStrategy(Strategy strategy); public Strategy getStrategy(int id); public void updateStrategy(Strategy strategy); public void deleteStrategy(int id); public List<Strategy> getStrategies(); }
package com.dtr.oas.service; import java.util.List; import com.dtr.oas.dao.StrategyDAO; import com.dtr.oas.model.Strategy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class StrategyServiceImpl implements StrategyService { @Autowired private StrategyDAO strategyDAO; @Override public void addStrategy(Strategy strategy) { strategyDAO.addStrategy(strategy); } @Override public void updateStrategy(Strategy strategy) { strategyDAO.updateStrategy(strategy); } @Override public Strategy getStrategy(int id) { return strategyDAO.getStrategy(id); } @Override public void deleteStrategy(int id) { strategyDAO.deleteStrategy(id); } @Override public List<Strategy> getStrategies() { return strategyDAO.getStrategies(); } }
8. The controller layer is next. We need to replace the default controller generated by STS and also create a controller for the strategy service.
package com.dtr.oas.controller; import org.springframework.stereotype.Controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class LinkController { @RequestMapping(value="/") public ModelAndView mainPage() { return new ModelAndView("home"); } @RequestMapping(value="/index") public ModelAndView indexPage() { return new ModelAndView("home"); } }
package com.dtr.oas.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import com.dtr.oas.model.Strategy; import com.dtr.oas.service.StrategyService; @Controller @RequestMapping(value="/strategy") public class StrategyController { @Autowired private StrategyService strategyService; @RequestMapping(value="/add", method=RequestMethod.GET) public ModelAndView addStrategyPage() { ModelAndView modelAndView = new ModelAndView("strategy-add"); modelAndView.addObject("strategy", new Strategy()); return modelAndView; } @RequestMapping(value="/add", method=RequestMethod.POST) public ModelAndView addingStrategy(@ModelAttribute Strategy strategy) { ModelAndView modelAndView = new ModelAndView("home"); strategyService.addStrategy(strategy); String message = "Strategy was successfully added."; modelAndView.addObject("message", message); return modelAndView; } @RequestMapping(value="/list") public ModelAndView listOfStrategies() { ModelAndView modelAndView = new ModelAndView("strategy-list"); List<strategy> strategies = strategyService.getStrategies(); modelAndView.addObject("strategies", strategies); return modelAndView; } @RequestMapping(value="/edit/{id}", method=RequestMethod.GET) public ModelAndView editStrategyPage(@PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("strategy-edit"); Strategy strategy = strategyService.getStrategy(id); modelAndView.addObject("strategy",strategy); return modelAndView; } @RequestMapping(value="/edit/{id}", method=RequestMethod.POST) public ModelAndView edditingStrategy(@ModelAttribute Strategy strategy, @PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("home"); strategyService.updateStrategy(strategy); String message = "Strategy was successfully edited."; modelAndView.addObject("message", message); return modelAndView; } @RequestMapping(value="/delete/{id}", method=RequestMethod.GET) public ModelAndView deleteStrategy(@PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView("home"); strategyService.deleteStrategy(id); String message = "Strategy was successfully deleted."; modelAndView.addObject("message", message); return modelAndView; } }
9. The last step is to create the JSPs. We will replace the home.jsp with a new one, and and the CRUD JSPs:
<?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Home page</title> </head> <body> <h1>Home page</h1> <p> ${message}<br/> <a href="${pageContext.request.contextPath}/strategy/add.html">Add New Strategy</a><br/> <a href="${pageContext.request.contextPath}/strategy/list.html">Strategy list</a><br/> </p> </body> </html>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>List of Strategies</title> </head> <body> <h1>List of strategies</h1> <p>Here you can see the list of the strategies, edit them, remove or update.</p> <table class="table table-striped" border="1px" cellpadding="0" cellspacing="0" > <thead> <tr> <th width="10%">id</th><th width="15%">name</th><th width="10%">type</th><th width="10%">actions</th> </tr> </thead> <tbody> <c:forEach var="strategy" items="${strategies}"> <tr> <td>${strategy.id}</td> <td>${strategy.name}</td> <td>${strategy.type}</td> <td> <a href="${pageContext.request.contextPath}/strategy/edit/${strategy.id}.html">Edit</a><br/> <a href="${pageContext.request.contextPath}/strategy/delete/${strategy.id}.html">Delete</a><br/> </td> </tr> </c:forEach> </tbody> </table> <p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p> </body> </html>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Add strategy page</title> </head> <body> <h1>Add strategy page</h1> <p>Here you can add a new strategy.</p> <form:form method="POST" commandName="strategy" action="${pageContext.request.contextPath}/strategy/add.html"> <table> <tbody> <tr> <td>Name:</td> <td><form:input path="name" /></td> </tr> <tr> <td>Type:</td> <td><form:input path="type" /></td> </tr> <tr> <td><input type="submit" value="Add" /></td> <td></td> </tr> </tbody> </table> </form:form> <p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p> </body> </html>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Edit strategy page</title> </head> <body> <h1>Edit strategy page</h1> <p>Here you can edit the existing strategy.</p> <p>${message}</p> <form:form method="POST" commandName="strategy" action="${pageContext.request.contextPath}/strategy/edit/${strategy.id}.html"> <table> <tbody> <tr> <td>Name:</td> <td><form:input path="name" /></td> </tr> <tr> <td>Type:</td> <td><form:input path="type" /></td> </tr> <tr> <td><input type="submit" value="Edit" /></td> <td></td> </tr> </tbody> </table> </form:form> <p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p> </body> </html>
10. After all of these steps, you should have a directory structure like the one below:
11. Right-click on the project -> Run As -> Run On Server and follow the steps in the wizard. When you run this project on the server, you should see a page similar to the one below.
Code at GitHub: https://github.com/dtr-trading/spring-ex02
Lastly, if you are looking for another example of this process, see the post:
http://fruzenshtein.com/spring-mvc-hibernate-maven-crud/.
29 comments:
Very good tutorial! You saved my day
I have only two typo errors that drove me crazy:
strategy-edit.jsp (line 15) : action="${pageContext.request.contextPath}/strategy/edit/${strategy.id}.html"
${team.id} => ${strategy.id}
and
StrategyController.java (line 40) : List strategies = strategyService.getStrategies();
List => List
Thanks
Excellent. I'm glad to hear you found this post useful!
Thanks,
Dave
Thanks for this tutorial
i have a question why you didn't use the web.xml in your project !!
Starting somewhere around Spring version 3.1, the options was provided to use either Java based configuration or XML based configuration...or a mix of the two. It's really personal preference whether you use one or the other.
I have scars from all of the XML config files in J2EE apps in the late '90s and early 2000s, so I tend to eliminate XML config when ever I can...it is a personal preference.
If you want to learn more about this configuration options in Spring MVC 4.x, take a look at:
http://docs.spring.io/spring/docs/4.0.3.RELEASE/spring-framework-reference/htmlsingle/#mvc-config
For information on the web.xml specifically, take a look at this api link:
http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html
Very good example...Thanks.
I have one doubt here in strategy-edit.jsp in action path you are passing "team.id" what is team here and how it is populated with strategy id?
Thanks in advance...
i think its not team.id it should be strategy.id
Thanks
Siva - good catch!
I'm not sure how I checked that code into Github and entered it into this blog entry. This code clearly could not function in its current form. I've updated the code in both Github and this blog.
Thanks!
Dave
thanks , works like a charm , but i need to increase my server timeout into 60 secs.
Also thanks for the git repo :) , i could build this project with no time
You're welcome. Happy to hear the code is working for you!
This example doesn't have web.xml file. Can you please upload it for us?
This example doesn't have web.xml file. Can you please upload it for us?
Hi Manivannan,
The short answer is that starting with Spring MVC 3.2/ Spring 3.2, there is support for Servlet 3.0. I'm running on Tomcat 7.0.50 and this version supports Servlet 3.0. With Servlet 3.0, the web.xml is not required if you use the proper annotations in your configuration files. Take a look at the links below for much more detail:
Spring MVC 4.0 web.xml info: http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/mvc.html
StackOverflow no web.xml: http://stackoverflow.com/questions/15008126/spring-mvc-and-servlets-3-0-do-you-still-need-web-xml
ZeroTurnAround no web.xml: http://zeroturnaround.com/rebellabs/your-next-java-web-app-less-xml-no-long-restarts-fewer-hassles-part-1/
Tomcat Servlet Spec Support: http://tomcat.apache.org/whichversion.html
Servlet 3.0 info: https://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html#annotations-vs-deployment-descriptor
I hope this answers your question. Please let me know if you have any other questions.
Thanks,
Dave
Good job. You seem to be the only one one so far who can provide a tutorial and source that actually works. Thanks!!!
Thank you for the comment...I appreciate the compliment!
Dave
Hello sir,
after running the program how do i access the pages
http://localhost:8080/spring-ex02/home.jsp
http://localhost:8080/spring-ex02/strategy-list.jsp
please help
The extensions should be .html rather than .jsp.
Also, when I run this application in Eclipse, using a configured Tomcat instance, a browser opens in the Eclipse IDE with the default page loaded.
I'm not sure if I answered your question, but if you have more questions/details I will try my best to answer them.
Thanks,
Dave
excellent example using java configuration... great job!!!!!
Thank you for your feedback...much appreciated!
Dave
Nice Article. Useful to understand Spring 4 + Hibernate integration.
Thank you for the comment...I appreciate your feedback!
Dave
The public type StrategyDAO must be defined in its own file StrategyDao.java how solve this error.
I write your program.It has not compile error.But when i run
HTTP Status 404 - /spring-ex02/
type Status report
message /spring-ex02/
description The requested resource is not available.
Apache Tomcat/8.0.30
when I run your project,I found 404.
hey please response my letter.
This is a poor example as long as you are using an entity in the controller layer, which is extremely discourage
Javier, agreed...please read the subsequent articles where the DTO packaged is introduced, and access to the entity layer is restricted.
Thanks,
Dave
Hi Jay Min,
Please provide more detail regarding your issue. You did not provide enough detail about the error you are experiencing and your configuration.
Thanks,
Dave
Looking forward to read all your artlces as I considere this website a good tool for developers. I forgot to say thank you in my previous message :)
thanks very much . I love you and love this project. Thanks agiang
Post a Comment