dineshonjava

Spring Restful Web Services JSON CRUD Example

In this spring rest tutorial, we will create restful web services Crud APIs by using HTTP verbs GET, POST, PUT and Delete and returning JSON representations of resources. In my previous post, we have created a very simple JAX-RS Restful web services but in this post we are using Spring REST, it will return response as json in this example. If you want to learn more about REST you could read my previous article What is REST? Architecture and it's Constraints.

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.

Step 1: Create a Dynamic web project using maven.

Project Structure
Spring Restful Web Services JSON CRUD Example

Download Source Code from GitHub
Spring Restful Web Services JSON CRUD Example


Step 2: Maven dependency for this application.
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>

Step 3: Creating Spring Configuration files for this application
In this spring restful web service application, we are using Java based configuration. So let's see following configuration java classes for this example.

a) Spring Configuration class for Spring MVC
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.

b) Spring Configuration for application Infrastructure
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.

Step 4: Creating Web Application Initializer file for this application
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[] { "/" };
 }
}


Step 5: Creating Application classes
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.

Step 6: Deploying this application to tomcat server

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/

rest-home-page

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.

Create-resource-POST-method

c) GET method: READ Account Resource using GET http method
Test our get method Spring REST service. You will get following output as below:

Read-Resource-Http-GET

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.

Spring Restful webservice Http PUT method

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.

Spring Restful webservice Http DELETE method

f) Read All Account Resources using GET http method

All accounts