Home  >  Spring Boot

Spring Boot REST Example

By Arvind Rai, February 22, 2018
This page will walk through Spring Boot RESTful web service CRUD example. REST is REpresentational State Transfer. REST or RESTful web services provide communication medium between software applications on the Internet. REST uses uniform and predefined set of stateless operations. RESTful web service can produce and consume JSON, XML and other media types. To create a Spring RESTful web service endpoint, we need to create a Spring controller annotated with @RestController. Spring provides @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping annotations to bind the request path with Spring controller methods. For CORS support, spring provides @CrossOrigin annotation that can be annotated at class level as well as method level. In Spring Boot application, to enable RESTful web service we need to include spring-boot-starter-web in our build files. It configures Jackson JSON library i.e. jackson-databind by default. Spring Boot RESTful web service produces JSON response when it detects Jackson JSON library in classpath and if it detects Jackson XML library then it produces XML response. For Jackson XML library we need to include jackson-dataformat-xml in our build files. Spring provides RestTemplate class to create RESTful web service client application. Here on this page we will create Spring RESTful web service CRUD example using CrudRepository and MySQL with complete detail step by step.

1. Technologies Used

Find the technologies being used in our example.
1. Java 9
2. Spring 5.0.5.RELEASE
3. Spring Boot 2.0.1.RELEASE
4. Maven 3.5.2
5. MySQL 5.5
6. Eclipse Oxygen

2. Maven Dependency

To work with Spring Boot RESTful web service, we need to provide spring-boot-starter-web Maven dependency as following.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency> 
The above Maven dependency by default collects the Jackson JSON library i.e. jackson-databind. Spring Boot REST gives JSON response by default because it detects jackson-databind in its classpath.
To support XML response in Spring Boot REST, we need to provide jackson-dataformat-xml library with spring-boot-starter-web. Find the Maven dependency.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.4</version>
</dependency> 
Include the above dependency in pom.xml and we are all set to get XML response.

3. RESTful Web Service URLs and Response Status Code for CRUD Operation

We will use following HTTP URLs, HTTP methods and response status code in our RESTful web service CRUD example.
1. Create :
HTTP Method: POST, URL: /user/article
HTTP Response Status Code: 201 CREATED and 409 CONFLICT

2. Read :
HTTP Method: GET, URL: /user/article/{id} (Fetches article by id)
HTTP Method: GET, URL: /user/articles (Fetches all articles)
HTTP Response Status Code: 200 OK

3. Update :
HTTP Method: PUT, URL: /user/article
HTTP Response Status Code: 200 OK

4. Delete :
HTTP Method: DELETE, URL: /user/article/{id}
HTTP Response Status Code: 204 NO CONTENT

Find the print screen of the JSON response of our RESTful web service example.
Spring Boot REST Example

4. RESTful Web Service Endpoint

To create a RESTful web service endpoint, we need to create a Spring controller annotated with @RestController . Here we have created endpoints for CRUD operations. We have created different web service methods to handle create, read, update and delete operations as given below.
@RestController
@RequestMapping("user")
@CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
	@Autowired
	private IArticleService articleService;
	
	//Fetches article by id
	@GetMapping("article/{id}")
	public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(articleService.getArticleById(id), ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Fetches all articles 
	@GetMapping(value="articles")
	public ResponseEntity<List<ArticleInfo>> getAllArticles() {
		List<ArticleInfo> responseArticleList = new ArrayList<>();
		List<Article> articleList = articleService.getAllArticles();
		for (int i = 0; i < articleList.size(); i++) {
			ArticleInfo ob = new ArticleInfo();
		    BeanUtils.copyProperties(articleList.get(i), ob);
		    responseArticleList.add(ob);    
		}
		return new ResponseEntity<List<ArticleInfo>>(responseArticleList, HttpStatus.OK);
	}
	
	//Creates a new article
	@PostMapping("article")
	public ResponseEntity<Void> addArticle(@RequestBody ArticleInfo articleInfo, UriComponentsBuilder builder) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);
                boolean flag = articleService.addArticle(article);
                if (flag == false) {
        	   return new ResponseEntity<Void>(HttpStatus.CONFLICT);
                }
                HttpHeaders headers = new HttpHeaders();
                headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri());
                return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
	}
	
	//Updates article
	@PutMapping("article")
	public ResponseEntity<ArticleInfo> updateArticle(@RequestBody ArticleInfo articleInfo) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);		
		articleService.updateArticle(article);
		
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(article, ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Deletes article by id
	@DeleteMapping("article/{id}")
	public ResponseEntity<Void> deleteArticle(@PathVariable("id") Integer id) {
		articleService.deleteArticle(id);
		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
	}	
} 
@RestController: It is used at class level to make RESTful web service endpoints. @RestController is combination of @Controller and @ResponseBody.
@CrossOrigin: It is used for CORS support that permits cross-origin requests on class level as well as method level.
@RequestMapping: It maps web requests onto methods in REST web service endpoints to provide flexible method signature.

@GetMapping: It is @RequestMapping with HTTP GET method.
@PostMapping: It is @RequestMapping with HTTP POST method.
@PutMapping: It is @RequestMapping with HTTP PUT method.
@DeleteMapping: It is @RequestMapping with HTTP DELETE method.
@PatchMapping: It is @RequestMapping with HTTP PATCH method.

@PathVariable: It indicates that a method parameter should be bound to a URI template variable.
@RequestBody: It is used with the method parameter to bind the body of the web request.
@RequestParam: It is used with method parameter to bind the web request parameter.

ResponseEntity: It is the extension of HttpEntity that represents HTTP request or response entity, consisting of headers and body.
UriComponentsBuilder: It is the builder for UriComponents that represents an immutable collection of URI components.

The annotations @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping are having optional elements as following.
consumes: It defines an array of consumable media types of mapped request.
produces: It defines an array of producible media types of mapped request.
headers: It defines the acceptable headers of mapped request.
params: It defines the parameters of the mapped request, narrowing the primary mapping.
path: It defines path mapping URIs in servlet environment.
name: It assigns a name to this mapping.
value: It defines primary mapping expressed by this annotation.

5. RESTful Web Service Client with RestTemplate

RestTemplate is the central class for synchronous client side HTTP access. RestTemplate communicates to RESTful web services using HTTP methods. Find some of RestTemplate methods.

getForObject: Retrieves data by using HTTP GET on specified URL.
postForLocation: Creates a new resource using given object to the URI template with HTTP POST method.
put: Creates or updates resource using given object to the URI template with HTTP PUT method.
delete: Deletes the resources at the specified URI.
exchange: It can execute any HTTP method to the given URI template. It returns ResponseEntity.

Find the sample example to execute RestTemplate.exchange method.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

String url = "http://localhost:8080/user/articles";

RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
ResponseEntity<Article[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article[].class); 
In the above code we are fetching all data of Article type using exchange with HTTP GET method. In our demo application, RestClientUtil.java contains client code.

6. @GetMapping

In RESTful web service @GetMapping is used to create endpoint that fetchs resources. @GetMapping is @RequestMapping with HTTP GET method. We have created a web service method to fetch data by id using @GetMapping.
@GetMapping("article/{id}")
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
   ArticleInfo ob = new ArticleInfo();
   BeanUtils.copyProperties(articleService.getArticleById(id), ob);
   return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
Suppose we want to fetch data for id 101. The RESTful web service URL will be /user/article/101 and it will listen on HTTP GET method. Above web service method will return data for that id with HTTP status 200 (Ok).

Client Code: To create client code for the above RESTful web service, we will use exchange method of RestTemplate with HTTP GET method.
public void getArticleByIdDemo() {
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON);
  RestTemplate restTemplate = new RestTemplate();
  String url = "http://localhost:8080/user/article/{id}";
  HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
  ResponseEntity<Article> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article.class, 101);
  Article article = responseEntity.getBody();
  System.out.println("Id:"+article.getArticleId()+", Title:"+article.getTitle()
                 +", Category:"+article.getCategory());      
} 

7. @PostMapping

In RESTful web service @PostMapping is used to create a web service endpoint that creates resource. @PostMapping is the @RequestMapping with HTTP POST method. We have created a web service method to create resource using @PostMapping as following.
@PostMapping("article")
public ResponseEntity<Void> addArticle(@RequestBody ArticleInfo articleInfo, UriComponentsBuilder builder) {
  Article article = new Article();
  BeanUtils.copyProperties(articleInfo, article);
  boolean flag = articleService.addArticle(article);
  if (flag == false) {
     return new ResponseEntity<Void>(HttpStatus.CONFLICT);
  }
  HttpHeaders headers = new HttpHeaders();
  headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri());
  return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
} 
To save a resource the RESTful web service URL will be /user/article that will listen on HTTP POST method. In the above code, we are creating the resource and returning the location of created data with HTTP status 201 (Created). If the resource is already available, we are returning HTTP status 409 (Conflict).

Client Code: To create client code, for above RESTful web service, we are using postForLocation method of RestTemplate.
public void addArticleDemo() {
   HttpHeaders headers = new HttpHeaders();
   headers.setContentType(MediaType.APPLICATION_JSON);
   RestTemplate restTemplate = new RestTemplate();
   String url = "http://localhost:8080/user/article";
   Article objArticle = new Article();
   objArticle.setTitle("Spring REST Security using Hibernate");
   objArticle.setCategory("Spring");
   HttpEntity<Article> requestEntity = new HttpEntity<Article>(objArticle, headers);
   URI uri = restTemplate.postForLocation(url, requestEntity);
   System.out.println(uri.getPath());    	
} 

8. @PutMapping

In RESTful web service @PutMapping is used to create a web service endpoint that creates or updates resource. @PutMapping is @RequestMapping with HTTP PUT method. We have created a web service method to update resource using @PutMapping as following.
@PutMapping("article")
  public ResponseEntity<ArticleInfo> updateArticle(@RequestBody ArticleInfo articleInfo) {
  Article article = new Article();
  BeanUtils.copyProperties(articleInfo, article);		
  articleService.updateArticle(article);

  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(article, ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
To update a resource the web service URL will be /user/article that will listen on HTTP PUT method. In the above code we are updating a resource and returning the updated resource with HTTP status 200 (Ok).

Client Code: To create client code, for above RESTful web service, we are using put method of RestTemplate.
public void updateArticleDemo() {
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON);
  RestTemplate restTemplate = new RestTemplate();
  String url = "http://localhost:8080/user/article";
  Article objArticle = new Article();
  objArticle.setArticleId(1);
  objArticle.setTitle("Update:Java Concurrency");
  objArticle.setCategory("Java");
  HttpEntity<Article> requestEntity = new HttpEntity<Article>(objArticle, headers);
  restTemplate.put(url, requestEntity);
} 

9. @DeleteMapping

In RESTful web service @DeleteMapping is used to create a web service endpoint that deletes a resource. @DeleteMapping is @RequestMapping with HTTP DELETE method. We have created a web service method to delete a resource using @DeleteMapping as following.
@DeleteMapping("article/{id}")
public ResponseEntity<Void> deleteArticle(@PathVariable("id") Integer id) {
   articleService.deleteArticle(id);
   return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
} 
Suppose we want to delete a resource with id 101. The web service URL will be /user/article/101 that will listen on HTTP DELETE method. In the above code we are deleting a resource for the given id and returning the HTTP status 204 (No Content).

Client Code: To create client code, for above RESTful web service, we are using exchange method of RestTemplate with HTTP DELETE method.
public void deleteArticleDemo() {
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON);
  RestTemplate restTemplate = new RestTemplate();
  String url = "http://localhost:8080/user/article/{id}";
  HttpEntity<Article> requestEntity = new HttpEntity<Article>(headers);
  restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, Void.class, 101);        
} 

10. Configure Producible and Consumable Media Types

A web service method can produce and consume primary media types by default. We can restrict to only configured media types to consume and produce. The annotations @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping are having optional elements as produces and consumes that is configured with required media types. Find the sample code.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_XML_VALUE },
	consumes= { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
Now the above web service method can only produce application/xml and consume application/json media types.
If we want to configure media types at class level that will be applicable for all its web service methods, we can do it using @RequestMapping as following.
@RestController
@RequestMapping(value= "user", produces= { MediaType.APPLICATION_XML_VALUE },
    consumes= { MediaType.APPLICATION_JSON_VALUE })
public class ArticleController {
------
} 

11. RESTful Web Service JSON Response

Spring uses the Jackson JSON library to automatically marshal instances of type resource into JSON. Our Spring RESTful web service application will produce JSON response by default if there is Jackson JSON library i.e. jackson-databind in the classpath. In Spring Boot application, the spring-boot-starter-web library by default includes jackson-databind library. To ignore null values in JSON response using Jackson JSON, we need to use @JsonInclude in our resource class.
public class ArticleInfo {
    @JsonInclude(Include.NON_NULL)
    private long articleId;

    @JsonInclude(Include.NON_NULL)
    private String title;

    @JsonInclude(Include.NON_NULL)
    private String category;

    //Getters and Setters
} 
Our web service methods can be restricted to produce only JSON response using produces element of mapping annotations such as @GetMapping.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
To configure HttpMessageConverter for JSON, we can create JavaConfig as following.
@Configuration 
@ComponentScan("com.concretepage") 
@EnableWebMvc   
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}

12. RESTful Web Service XML Response

To get XML response by our Spring RESTful web service, we need to include Jackson XML library i.e. jackson-dataformat-xml library in our application classpath. Find the maven dependency for jackson-dataformat-xml library.
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.4</version>
</dependency> 
We just need to include above Maven dependency in pom.xml and we are all set to get XML response. We can use @JacksonXmlProperty annotation in our resource class to change local name etc.
@JacksonXmlRootElement(localName="article", namespace="com.concretepage")
public class ArticleInfo {
    @JacksonXmlProperty(localName="articleId")
    private long articleId;

    @JacksonXmlProperty(localName="title")
    private String title;

    @JacksonXmlProperty(localName="category")
    private String category;

    //Getters and Setters
} 
Our web service methods can be restricted to produce only XML response using produces element of mapping annotations such as @GetMapping.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
To configure HttpMessageConverter for XML, we can create JavaConfig as following.
@Configuration 
@ComponentScan("com.concretepage") 
@EnableWebMvc   
public class AppConfig extends WebMvcConfigurerAdapter {  
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
        builder.indentOutput(true);
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));
    }	
} 

13. CORS Support

For CORS support, Spring provides @CrossOrigin annotation. This annotation can be used at class level as well as method level in RESTful Web service controller. Find the sample code to use it at class level.
@RestController
@RequestMapping("user")
@CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
------
} 
In the above code we have configured origin for CORS support as http://localhost:4200 . It means a web application running at URL http://localhost:4200 can only access our RESTful web service application.

14. Spring REST CRUD + CrudRepository + MySQL Complete Example

Now we will provide here complete code of our demo application. We will perform here Spring REST operation. We are using MySQL database and for database query we are using CrudRepository. We have created two demo applications, one for JSON response and another for XML response. Here we are providing code for JSON response application and has given the changes required for XML response. At the end of the article we have provided source code download link for both the applications.

14.1 Project Structure in Eclipse

Find the project structure in Eclipse.
Spring Boot REST Example

14.2 Maven Dependencies used in Project

Find the Maven file used in the project.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.concretepage</groupId>
	<artifactId>spring-boot-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>spring-boot-demo</name>
	<description>Spring Boot Application</description>
	<parent>
	    <groupId>org.springframework.boot</groupId>
  	    <artifactId>spring-boot-starter-parent</artifactId>
	    <version>2.0.1.RELEASE</version>
 	    <relativePath/>
	</parent>
	<properties>
	    <java.version>9</java.version>
	</properties>
	<dependencies>
	  <dependency>
		 <groupId>org.springframework.boot</groupId>
		 <artifactId>spring-boot-starter-web</artifactId>
	  </dependency>
	  <dependency>
		 <groupId>org.springframework.boot</groupId>
		 <artifactId>spring-boot-starter-data-jpa</artifactId>
	  </dependency>
	  <dependency>
		 <groupId>mysql</groupId>
		 <artifactId>mysql-connector-java</artifactId>
		 <version>6.0.5</version>
	  </dependency>	  	  	  
	  <dependency>
		 <groupId>javax.xml.bind</groupId>
		 <artifactId>jaxb-api</artifactId>
		 <version>2.3.0</version>
	  </dependency>  	
          <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-devtools</artifactId>
                 <optional>true</optional>
          </dependency> 
	</dependencies>
	<build>
	  <plugins>
		 <plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		 </plugin>
	  </plugins>
	</build>
</project>  
Find the description of spring boot starter configured in maven file.
spring-boot-starter-parent: Parent POM for dependency management.
spring-boot-starter-web: Starter for building web, REST applications. It uses tomcat server as default embedded server.
spring-boot-starter-data-jpa: Starter for spring data JPA with hibernate.
spring-boot-devtools: It provides developer tools. These tools are helpful in application development mode. One of the features of developer tool is automatic restart of the server for any change in code.
spring-boot-maven-plugin: It is used to create executable JAR of the application.

The above Maven file will give JSON response. To get XML response, we need to add following dependency.
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.4</version>
</dependency> 
jackson-dataformat-xml: Provides Jackson XML library.

14.3 MySQL Database used in Project

CREATE DATABASE IF NOT EXISTS `concretepage`;
USE `concretepage`;

CREATE TABLE IF NOT EXISTS `articles` (
  `article_id` bigint(5) NOT NULL AUTO_INCREMENT,
  `title` varchar(200) NOT NULL,
  `category` varchar(100) NOT NULL,
  PRIMARY KEY (`article_id`)
) ENGINE=InnoDB;

INSERT INTO `articles` (`article_id`, `title`, `category`) VALUES
	(1, 'Java Concurrency', 'Java'),
	(2, 'Spring Boot Getting Started', 'Spring Boot'),
	(3, 'Lambda Expressions Java 8 Example', 'Java 8'); 

14.4 Repository and Service

ArticleRepository.java
package com.concretepage.repository;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import com.concretepage.entity.Article;
public interface ArticleRepository extends CrudRepository<Article, Long>  {
    List<Article> findByTitle(String title);
    List<Article> findDistinctByCategory(String category);
    List<Article> findByTitleAndCategory(String title, String category);
} 
Article.java
package com.concretepage.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="articles")
public class Article implements Serializable { 
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="article_id")
        private long articleId;  
	@Column(name="title")
        private String title;
	@Column(name="category")	
	private String category;
	public long getArticleId() {
		return articleId;
	}
	public void setArticleId(long articleId) {
		this.articleId = articleId;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	}
} 
IArticleService.java
package com.concretepage.service;
import java.util.List;
import com.concretepage.entity.Article;
public interface IArticleService {
     List<Article> getAllArticles();
     Article getArticleById(long articleId);
     boolean addArticle(Article article);
     void updateArticle(Article article);
     void deleteArticle(int articleId);
} 
ArticleService.java
package com.concretepage.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.concretepage.entity.Article;
import com.concretepage.repository.ArticleRepository;
@Service
public class ArticleService implements IArticleService {
	@Autowired
	private ArticleRepository articleRepository;
	@Override
	public Article getArticleById(long articleId) {
		Article obj = articleRepository.findById(articleId).get();
		return obj;
	}	
	@Override
	public List<Article> getAllArticles(){
		List<Article> list = new ArrayList<>();
		articleRepository.findAll().forEach(e -> list.add(e));
		return list;
	}
	@Override
	public synchronized boolean addArticle(Article article){
	        List<Article> list = articleRepository.findByTitleAndCategory(article.getTitle(), article.getCategory()); 	
                  if (list.size() > 0) {
    	          return false;
                } else {
    	          articleRepository.save(article);
    	          return true;
                }
	}
	@Override
	public void updateArticle(Article article) {
		articleRepository.save(article);
	}
	@Override
	public void deleteArticle(int articleId) {
		articleRepository.delete(getArticleById(articleId));
	}
}

14.5 Application Property File

Datasource, JPA properties and logging etc need to be configured in application.properties file located in the classpath of Spring boot application. These properties will automatically be read by Spring boot. application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/concretepage
spring.datasource.username=root
spring.datasource.password=cp

spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=12
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.format_sql=true

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE 
In Spring Boot 2.0 release, default database pooling technology has been switched from Tomcat Pool to HikariCP. spring-boot-starter-jdbc and spring-boot-starter-data-jpa resolve HikariCP dependency by default and spring.datasource.type property has HikariDataSource as default value. The datasource properties starting with spring.datasource.* will automatically be read by Spring boot JPA. To change the Hibernate properties we will use prefix spring.jpa.properties.* with Hibernate property names. On the basis of given data source URL, Spring Boot can automatically identify data source driver class. So we need not to configure diver class.

14.6 Create Controller

ArticleController.java
package com.concretepage.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import com.concretepage.entity.Article;
import com.concretepage.service.IArticleService;
@RestController
@RequestMapping("user")
@CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
	@Autowired
	private IArticleService articleService;
	
	//Fetches article by id
	@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_JSON_VALUE })
	public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(articleService.getArticleById(id), ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Fetches all articles 
	@GetMapping(value= "articles", produces= { MediaType.APPLICATION_JSON_VALUE })
	public ResponseEntity<List<ArticleInfo>> getAllArticles() {
		List<ArticleInfo> responseArticleList = new ArrayList<>();
		List<Article> articleList = articleService.getAllArticles();
		for (int i = 0; i < articleList.size(); i++) {
			ArticleInfo ob = new ArticleInfo();
		    BeanUtils.copyProperties(articleList.get(i), ob);
		    responseArticleList.add(ob);    
		}
		return new ResponseEntity<List<ArticleInfo>>(responseArticleList, HttpStatus.OK);
	}
	
	//Creates a new article
	@PostMapping(value= "article", produces= { MediaType.APPLICATION_JSON_VALUE })
	public ResponseEntity<Void> addArticle(@RequestBody ArticleInfo articleInfo, UriComponentsBuilder builder) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);
                boolean flag = articleService.addArticle(article);
                if (flag == false) {
        	   return new ResponseEntity<Void>(HttpStatus.CONFLICT);
                }
                HttpHeaders headers = new HttpHeaders();
                headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri());
                return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
	}
	
	//Updates article
	@PutMapping(value= "article", produces= { MediaType.APPLICATION_JSON_VALUE })
	public ResponseEntity<ArticleInfo> updateArticle(@RequestBody ArticleInfo articleInfo) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);		
		articleService.updateArticle(article);
		
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(article, ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Deletes article by id
	@DeleteMapping(value= "article/{id}", produces= { MediaType.APPLICATION_JSON_VALUE })
	public ResponseEntity<Void> deleteArticle(@PathVariable("id") Integer id) {
		articleService.deleteArticle(id);
		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
	}	
} 
In the above controller we have restricted the producible media type only to MediaType.APPLICATION_JSON_VALUE in our JSON response demo application. In our XML response demo application, we are using producible media type as MediaType.APPLICATION_XML_VALUE.

Find the ArticleInfo.java for JSON.
ArticleInfo.java
package com.concretepage.controller;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
public class ArticleInfo {
	@JsonInclude(Include.NON_NULL)
        private long articleId;
	@JsonInclude(Include.NON_NULL)
        private String title;
	@JsonInclude(Include.NON_NULL)
        private String category;
	public long getArticleId() {
		return articleId;
	}
	public void setArticleId(long articleId) {
		this.articleId = articleId;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	} 
} 
Find the ArticleInfo.java for XML.
ArticleInfo.java
package com.concretepage.controller;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
@JacksonXmlRootElement(localName="article", namespace="com.concretepage")
public class ArticleInfo {
	@JacksonXmlProperty(localName="articleId")
        private long articleId;
	@JacksonXmlProperty(localName="title")
        private String title;
	@JacksonXmlProperty(localName="category")
        private String category;
	public long getArticleId() {
		return articleId;
	}
	public void setArticleId(long articleId) {
		this.articleId = articleId;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	} 
} 

14.7 Class with Main Method using SpringApplication

To run Spring Boot application, we need to create a class with main method using SpringApplication and annotated with @SpringBootApplication as following.
MyApplication.java
package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {  
	public static void main(String[] args) {
		SpringApplication.run(MyApplication.class, args);
        }       
} 
@SpringBootApplication annotation is the combination of @Configuration, @EnableAutoConfiguration and @ComponentScan annotations.

15. Test Application

To test the application, first create table in MySQL as given in the example. Then we can run REST web service in following ways.
1. Using Maven Command: Download the project source code. Go to the root folder of the project using command prompt and run the command.
mvn spring-boot:run 
Tomcat server will be started.

2. Using Eclipse: Download the project source code using the download link given at the end of article. Import the project into eclipse. Using command prompt, go to the root folder of the project and run.
mvn clean eclipse:eclipse 
and then refresh the project in eclipse. Run Main class MyApplication by clicking Run as -> Java Application. Tomcat server will be started.

3. Using Executable JAR: Using command prompt, go to the root folder of the project and run the command.
mvn clean package 
We will get executable JAR spring-boot-demo-0.0.1-SNAPSHOT.jar in target folder. Run this JAR as
java -jar target/spring-boot-demo-0.0.1-SNAPSHOT.jar 
Tomcat server will be started.

Now we are ready to test the application. To run web service client, go to the RestClientUtil class in eclipse and click on Run as -> Java Application. We can also use Postman to test the application. Find the print screen for XML response.
Spring Boot REST Example

16. References

Spring Boot Reference Guide
Spring Boot CrudRepository Example

17. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS


©2018 concretepage.com | Privacy Policy | Contact Us