Here we are using Spring 4.3.5 webmvc, Spring REST, Spring Data JPA and jackson libraries for this example. For back-end we are using H2 in-memory database for saving the data and also using Spring Data JPA over the Hibernate JPA as ORM. Let’s see steps to create a simple Spring Restful web services crud example which will return json.
In pom.xml, there are following dependency required for this application.
<properties> <spring.version>4.3.5.RELEASE</spring.version> <spring.data.version>1.11.1.RELEASE</spring.data.version> <h2.version>1.4.193</h2.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>${spring.data.version}</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>${h2.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.1.0.Final</version> </dependency> <!-- Jackson JSON Mapper --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.0</version> </dependency> </dependencies>
In the maven file we have dependencies of spring webmvc, spring data jpa, h2 database and hibernate entity manager for jpa transaction. Also we have to include jackson maven dependencies into classpath of your application because spring will register Jackson2JsonMessageConverter class automatically into context. Whenever we request resource as json with accept headers=”Accept=application/json”, then Jackson2JsonMessageConverter comes into picture and convert resource to json format.
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.0</version> </dependency>
In this spring restful web service application, we are using Java based configuration. So let’s see following configuration java classes for this example.
The following file is required for configuring spring mvc to the application and enabling required bean post processors for message converter.
RestApplicationConfig.java
/** * */ package com.doj.restapi.web.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; /** * @author Dinesh.Rajput * */ @Configuration @EnableWebMvc @ComponentScan("com.doj.restapi.web.controller") public class RestApplicationConfig{ }
@EnableWebMvc- It used for enabling spring mvc behavior i.e. it is responsible for registering Spring MVC required Bean Post Processors in the application as like Jackson2JsonMessageConverter etc.
@ComponentScan- It scans the package com.doj.restapi.web.controller. This package has Rest Controllers for this application.
This file has configuration about application core services like DB connection, DataSource and also scan the packages for service classes and repositories i.e. Non web components.
InfrastructureConfig.java
/** * */ package com.doj.restapi.config; import javax.persistence.EntityManagerFactory; 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.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; /** * @author Dinesh.Rajput * */ @Configuration @ComponentScan("com.doj.restapi.service") @EnableJpaRepositories("com.doj.restapi.repository") public class InfrastructureConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build(); } @Bean public JpaVendorAdapter jpaVendorAdapter() { HibernateJpaVendorAdapter bean = new HibernateJpaVendorAdapter(); bean.setDatabase(Database.H2); bean.setGenerateDdl(true); return bean; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory( DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) { LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean(); bean.setDataSource(dataSource); bean.setJpaVendorAdapter(jpaVendorAdapter); bean.setPackagesToScan("com.doj.restapi.bean"); return bean; } @Bean public JpaTransactionManager transactionManager(EntityManagerFactory emf) { return new JpaTransactionManager(emf); } }
@EnableJpaRepositories-It used to create the spring bean related to spring data jpa in the application i.e. those classes which implement spring data repository interfaces.
Here we are using Java based configuration for web application i.e. here we do not have web.xml file in the application. For java based web configuration, we have to required at least tomcat 7 and servlet 3.0 or above.
RestApplicationInitializer.java
/** * */ package com.doj.restapi.web; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import com.doj.restapi.config.InfrastructureConfig; import com.doj.restapi.web.config.RestApplicationConfig; /** * @author Dinesh.Rajput * */ public class RestApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { InfrastructureConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { RestApplicationConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
In this application, we will create and read account resource from account repository.
a) Create a Controller AccountController.java
/** * */ package com.doj.restapi.web.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.doj.restapi.bean.Account; import com.doj.restapi.service.IAccountService; /** * @author Dinesh.Rajput * */ @RestController public class AccountController { @Autowired IAccountService accountService; @GetMapping("/") public String home (){ return "Spring REST Dinesh on Java!!!"; } @GetMapping("/accounts") public List<Account> all (){ return accountService.list(); } @PostMapping("/account") public Account create (@RequestBody Account account){ return accountService.create(account); } @GetMapping("/account/{accountId}") public Account get (@PathVariable Long accountId){ return accountService.get(accountId); } @PutMapping("/account/{accountId}") public Account update (@RequestBody Account account, @PathVariable Long accountId){ return accountService.update(account, accountId); } @DeleteMapping("/account/{accountId}") public void delete (@PathVariable Long accountId){ accountService.delete(accountId); } }
This controller class is annotated with @RestController annotation instead of @Controller annotation. As of spring 4.0, we can use @RestController which is combination of @Controller and @ResponseBody. Read my article RestController in Spring Framework 4.0 for more detail.
@RestController = @Controller + @ResponseBody
Before Spring 4.0, we have to use @Controller at the class level with @ResponseBody before the handler method as below:
@Controller public class AccountController { ..... ..... @RequestMapping("/account/{accountId}") public @ResponseBody Account get (@PathVariable Long accountId){ return accountService.get(accountId); } ..... ..... }
In this example, we are using @GetMapping, @PostMapping, @PutMapping and @DeleteMapping annotations, these annotations are introduced from Spring 4.3 version in parallel of @RequestMapping with Http Methods annotation as below.
@GetMapping = @RequestMapping + Http GET method
b) Create a Bean class Account.java
/** * */ package com.doj.restapi.bean; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; /** * @author Dinesh.Rajput * */ @Entity @Table public class Account implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue public Long accountId; public String name; public String city; public Double balance; public Account() { super(); } public Account(String name, String city, Double balance) { super(); this.name = name; this.city = city; this.balance = balance; } public Long getAccountId() { return accountId; } public void setAccountId(Long accountId) { this.accountId = accountId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public Double getBalance() { return balance; } public void setBalance(Double balance) { this.balance = balance; } @Override public String toString() { return "Account [accountId=" + accountId + ", name=" + name + ", city=" + city + ", balance=" + balance + "]"; } }
c) Create a Service class AccountService.java
This class has CRUD method service for account resource.
/** * */ package com.doj.restapi.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.doj.restapi.bean.Account; import com.doj.restapi.repository.AccountRepository; /** * @author Dinesh.Rajput * */ @Service public class AccountService implements IAccountService{ @Autowired AccountRepository accountRepository; @Override public Account create(Account account) { return accountRepository.save(account); } @Override public Account get(Long accountId) { return accountRepository.findOne(accountId); } @Override public Account update(Account account, Long accountId) { return accountRepository.save(account); } @Override public void delete(Long accountId) { accountRepository.delete(accountId); } @Override public List<Account> list() { return (List<Account>) accountRepository.findAll(); } }
d) Create a Repository class AccountRepository.java
This is an interface which extends an interface of Spring Data JPA for using CRUD operation over account class.
/** * */ package com.doj.restapi.repository; import org.springframework.data.repository.CrudRepository; import com.doj.restapi.bean.Account; /** * @author Dinesh.Rajput * */ public interface AccountRepository extends CrudRepository<Account, Long> { }
This interface is extending an interface CrudRepository of Spring Data JPA library. As you seen, there is no method in the interface, so we are using default CRUD operation methods of CrudRepository interface.
Right click on project -> run as -> run on server
After starting of tomcat server, Let’s check our application with Rest client Postman, it is UI based client for testing restful web applications, we have below URL of our application to provide start page:
a) Home Page
http://localhost:8080/restapi/
Postman is chrome plugin. Launch postman.
b) POST method: CREATE Account Resource using POST http method
Post method is used to create new resource. Here we are adding new Account to the account database, so you can see we have used account json in post body.
c) GET method: READ Account Resource using GET http method
Test our get method Spring REST service. You will get following output as below:
d) PUT method: UPDATE Account Resource using PUT http method
Put method is used to update resource. Here we will update name of account holder of accountId=1 using put method. So we will update account json in body of request of accountId is 1 as below.
e) DELETE method: DELETE Account Resource using DELETE http method
Delete method is used to delete resource. So here we will pass accountId of account which needs to be deleted as Path Param. We are going delete the account who have accountId=3.
f) Read All Account Resources using GET http method
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…