8621. Creating RESTful Web Services with Spring BootSpring Boot, RESTful, and Maven
Build RESTful Web Service with Spring Boot and Maven in Java.
1. Setup
1.1 Java Development Environment
Install JDK, Eclipse and Tomcat first.
1.2 Maven
In addition, we will use maven as build tool. So Maven is also required to be installed.
$ brew install maven // Mac OS
$ sudo apt-get install maven // Linux
Check maven version.
$ mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2016-02-20T12:39:06-07:00)
Maven home: /usr/local/Cellar/maven/3.5.0/libexec
Java version: 1.8.0_101, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.6", arch: "x86_64", family: "mac"
2. SpringBoot Project
2.1 Enabling Maven Index
In Eclipse, top menu Eclipse -> Preferences, and then choose Maven in the left side. Check the box ‘Download repository index updates on startup’. Optionally, check the boxes ‘Download Artifact Sources’ and ‘Download Artifact JavaDoc’.
2.2 Rebuilding Index
In Eclipse, Window -> Show View -> Other -> Maven -> Maven Repositories, tick ‘Full Index Enabled’ and then ‘Rebuild Index’ for ‘Global Repositories’.
2.2 Creating Maven Project
1) In Eclipse, File -> New -> ‘Maven Project’, check the box ‘Create a simple project’-> Next, Name: SpringBootTutorial
In the new created project, there are two main branches, one is for source code, another is for test.
2.2 Specifying Java Version
Since, we will use lamda expression, specify java version to java 8 in pom.xml.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
2.3 Adding Dependency
Add spring boot dependency to pom.xml.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Starter for using Spring Data JPA with Hibernate.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Use H2 in-memory database.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
2.4 Creating Service
1) Create Package
Right click project SpringBootTutorial->src->main->java>New->Package, Package Name: johnny.tutorial.SpringBootTutorial
2) Create Executable Application
RestApplication.java with dummy data.
package johnny.tutorial.SpringBootTutorial;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import johnny.tutorial.SpringBootTutorial.domain.Product;
import johnny.tutorial.SpringBootTutorial.repository.ProductRepository;
@SpringBootApplication
public class RestApplication {
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
@Bean
CommandLineRunner runner(ProductRepository productRepository) {
return args -> {
Product product1 = new Product("iPhone 7s");
product1.setPrice(700.00);
productRepository.save(product1);
Product product2 = new Product("iPad 4");
product2.setPrice(500.00);
productRepository.save(product2);
Product product3 = new Product("iPod");
product3.setPrice(300.00);
productRepository.save(product3);
};
}
}
Create folder domain and create class Product in domain.
Product.java
package johnny.tutorial.SpringBootTutorial.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
private double price;
@SuppressWarnings("unused")
private Product(){}
public Product(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + "]";
}
}
Create folder repository and create interface ProductRepository in repository. ProductRepository.java
package johnny.tutorial.SpringBootTutorial.repository;
import org.springframework.data.repository.CrudRepository;
import johnny.tutorial.SpringBootTutorial.domain.Product;
public interface ProductRepository extends CrudRepository<Product, Long> {
}
Create folder service and create interface ProductService in serice folder, and create ProductService.java
package johnny.tutorial.SpringBootTutorial.service;
import johnny.tutorial.SpringBootTutorial.domain.Product;
public interface ProductService {
Iterable<Product> list();
Product create(Product product);
Product read(long id);
Product update(long id, Product product);
void delete(long id);
}
ProductServiceImpl.java
package johnny.tutorial.SpringBootTutorial.service;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import johnny.tutorial.SpringBootTutorial.domain.Product;
import johnny.tutorial.SpringBootTutorial.repository.ProductRepository;
public class ProductServiceImpl implements ProductService {
private ProductRepository productRepository;
@Autowired
public ProductServiceImpl(ProductRepository postRepository){
this.productRepository = productRepository;
}
@Override
public Iterable<Product> list() {
return productRepository.findAll();
}
@Override
public Product read(long id) {
return productRepository.findOne(id);
}
@Override
@Transactional
public Product create(Product product) {
// save the new product
return productRepository.save(product);
}
@Override
public void delete(long id) {
productRepository.delete(id);
}
@Override
public Product update(long id, Product update) {
Product product = productRepository.findOne(id);
if( update.getName() != null ) {
product.setName(update.getName());
}
return productRepository.save(product);
}
}
Finally, create controller folder and create ProductController in controller.
package johnny.tutorial.SpringBootTutorial.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import johnny.tutorial.SpringBootTutorial.domain.Product;
import johnny.tutorial.SpringBootTutorial.repository.ProductRepository;
@RestController
@RequestMapping("/products")
public class ProductController {
ProductRepository productRepository;
@Autowired
public ProductController(ProductRepository productRepository){
this.productRepository = productRepository;
}
@RequestMapping("/")
public Iterable<Product> list(){
return productRepository.findAll();
}
@RequestMapping("/{id}")
public Product read(@PathVariable(value="id") long id){
return productRepository.findOne(id);
}
}
2.5 Project Structure
This is the final structure of this tutorial project.
2.6 Running and Testing
run spring boot project with maven
$ mvn spring-boot:run
Use Postman to access http://localhost:8080/ for testing.
1) Get Product List
URL: http://localhost:8080/products/
2) Get Product by ID
URL: http://localhost:8080/product/1
3. Supporting XML
3.1 Adding Dependency to pom.xml
<dependencies>
...
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
3.2 Running and Testing
restart spring boot.
$ mvn spring-boot:run
In Postman, add Accept = “application/xml” to Header.
URL: http://localhost:8080/products/1
4. Enabling Autoload
Add dependency of Spring Dev-Tool in pom.xml
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
change the name and price of product1.
Don’t restart maven. Just send request again. The new product is returned.
5. Debugging
1) In Eclipse, set breakpoint inside the method(eg. StringController.java->reverse()) you want to debug.
2) Right click on the RestApplication.java, choose “Debug As” -> “Java Application”.
3) In postman, access the url to trigger method being called. You should see breakpoint is activated.
6. Source Files
7. Reference
- Spring Boot Official Website
- Building an Application with Spring Boot
- Developing your first Spring Boot application
- Free Introducing Spring Boot Course on Udemy
- Building a RESTful Web Service
- Building a RESTful Web Service with Spring Boot Actuator
- DevTools in Spring Boot 1.3
- H2 Database Tutorial
- JUnit and Maven in Eclipse
- Spring Boot Rest API Example
- SPRING BOOT DEVELOPMENT WITH DOCKER
- Spring Boot Tutorials
- Maven Tutorial