This tutorial combines both
1) Spring 4 MVC RESTful Web Service Beginner Tutorial step by step, which focuses on the RSTful web service and
2) JPA with Hibernate & MySQL database tutorial step by step, which focuses on JPA and Hibernate.
Controller –> Service Layer –> DAO Layer –> JPA/Hibernate –> MySQL Database
Step 1: Create a maven based Java project from a command-line.
1 | mvn archetype:generate -B -DgroupId=com.mytutorial -DartifactId=simple-orm-persistence |
Step 2: Import the project into Eclipse as “File” –> “Import” –> “Existing Maven Projects”.
Step 3: The pom.xml with “jackson-databind“, which will be used to convert the response data into JSON string, and “jackson-dataformat-xml“, which will be used to convert the response data to XML. Spring MVC, JPA, and Hibernate libraries are included as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mytutorial</groupId> <artifactId>simple-orm-persistence</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>simple-orm-persistence</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL Driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> <!-- For connection pooling --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.2.10.Final</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0.2</version> </dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.2.10.Final</version> <exclusions> <exclusion> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> </exclusion> </exclusions> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>compile</scope> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.9.RELEASE</version> </dependency> <!-- JSON data binding --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.9</version> </dependency> <!-- XML data binding --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.8.9</version> </dependency> </dependencies> <build> <finalName>simpleWeb</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.1.0</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project> |
Define the model class Account.java
Step 4: Define the Account.java with 3 fields & getters/setters in the package “com.mytutorial.model”. This has JPA annotations to map “learnjavadb” databse table “account” columns via Hibernate as implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | package com.mytutorial.model; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "account") public class Account { @Id private String id; private String name; private float balance; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getBalance() { return balance; } public void setBalance(float balance) { this.balance = balance; } @Override public String toString() { return "Account [id=" + id + ", name=" + name + ", balance=" + balance + "]"; } } |
Define the controller class AccountController.java
Step 5: Define the AccountController.java to handle HTTP requests in the package “com.mytutorial.controller”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.mytutorial.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.mytutorial.model.Account; import com.mytutorial.service.AccountService; @RestController @RequestMapping("/v1/forecasting") public class AccountController { @Autowired private AccountService accountService; @RequestMapping(value = "/accounts", method = RequestMethod.GET) public List<Account> getAccounts() { List<Account> accounts = accountService.getAccounts(); return accounts; } } |
Spring Java Configs for wiring up
Step 6: Spring Java configs in the package “com.mytutorial.config”
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.mytutorial.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.mytutorial.controller") public class SimpleWebConfiguration { } |
Bootstrap the Spring dispatcher Servlet with the mapping URI of “/entry/*” & the above “SimpleWebConfiguration” for the controllers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.mytutorial.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SimpleWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SimpleWebConfiguration.class}; } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[] { "/entry/*" }; } } |
Step 7: The Service layer that talks to the DAO layer. Create a package “com.mytutorial.service” and add the following interface & implementation.
1 2 3 4 5 6 7 8 9 10 11 | package com.mytutorial.service; import java.util.List; import com.mytutorial.model.Account; public interface AccountService { public List<Account> getAccounts(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.mytutorial.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.mytutorial.dao.AccountDao; import com.mytutorial.model.Account; @Service public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override public List<Account> getAccounts() { return accountDao.getAccounts(); } } |
Step 8: Before writing the DAO layer, define the “persistence.xml” in “src/main/resources/META-INF” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="jpa-example" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/learnjavadb" /> <property name="javax.persistence.jdbc.user" value="user123" /> <property name="javax.persistence.jdbc.password" value="pwd123" /> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> <property name="hibernate.hbm2ddl.auto" value="validate" /> <!-- Configuring Connection Pool --> <property name="hibernate.c3p0.min_size" value="5" /> <property name="hibernate.c3p0.max_size" value="20" /> <property name="hibernate.c3p0.timeout" value="500" /> <property name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.idle_test_period" value="2000" /> </properties> </persistence-unit> </persistence> |
Step 9: Use “jpa-example” persistent unit to get an entity manager. Create a package “com.mytutorial.util”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package com.mytutorial.util; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public enum PersistenceManager { INSTANCE; private EntityManagerFactory emFactory; private PersistenceManager() { emFactory = Persistence.createEntityManagerFactory("jpa-example"); } public EntityManager getEntityManager() { return emFactory.createEntityManager(); } public void close() { emFactory.close(); } } |
Step 10: The DAO layer that talks to the MySQL database. Create a package “com.mytutorial.dao” and add the following interface & implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package com.mytutorial.dao; import java.util.List; import com.mytutorial.model.Account; public interface AccountDao { public List<Account> getAccounts(); public boolean saveAccount(Account account); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package com.mytutorial.dao; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import org.springframework.stereotype.Repository; import com.mytutorial.model.Account; import com.mytutorial.util.PersistenceManager; @Repository public class AccountDaoImpl implements AccountDao { @SuppressWarnings("unchecked") @Override public List<Account> getAccounts() { EntityManager em = PersistenceManager.INSTANCE.getEntityManager(); Query query = em.createQuery("SELECT a FROM Account a"); List<Account> result = query.getResultList(); return result; } @Override public boolean saveAccount(Account account) { EntityManager em = PersistenceManager.INSTANCE.getEntityManager(); em.getTransaction().begin(); em.persist(account); em.getTransaction().commit(); return true; } } |
Build simpleWeb.war & deploy to Tomcat
Step 11: Copy the “simpleWeb.war” to Tomcat’s “webapps” folder and start the Tomcat server.
1 2 | c:\tools\apache-tomcat-9.0.0.M21-windows-x64\apache-tomcat-9.0.0.M21\bin>startup.bat |
Start the MySQL database server
Step 12: The dataase server must be running. The “learnjavadb” database was already created with the table “account”.
1 2 | c:\scripts>mysqld --console |
Start the RESTClient from WizTools.org
Step 13: Double-Clicking “c:\tools\restclient-ui-3.2.2-jar-with-dependencies.jar” on windows or
1 2 | c:\tools>java -jar restclient-ui-3.2.2-jar-with-dependencies.jar |
XML Data
http://localhost:8080/simpleWeb/entry/v1/forecasting/accounts
JSON Data
http://localhost:8080/simpleWeb/entry/v1/forecasting/accounts.json