Spring Data REST

Spring Data REST

2018/9/14

2019/01/20 (增加連結)

基本概念

REST (Representational state transfer)是提供web services的一種方法,REST利用HTTP的POST,GET , PUT, DELETE來進行CRUD。

Spring framework提供不同方式來提供REST service,最新也最簡單的就是使用data rest。

設定

pom.xml,使用spring framework提供的data rest,因為我們直接套用JPA,所以,也需要那部份的package:

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
      </dependency>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
      </dependency>

      <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
      </dependency>

application.properties (詳參: Spring JPA)

#disbale Spring banner
#spring.main.banner-mode=off

# Loads SQL scripts? schema.sql and data.sql
#spring.datasource.initialize=true

spring.datasource.url=jdbc:mysql://localhost/practice?verifyServerCertificate=false&useSSL=false&requireSSL=false
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

資料庫設定

第一、要安裝mySQL server (或其他資料庫)

第二、要啟動mySQL server (或其他資料庫) (請參考投影片)

第三、要建立資料表 (或匯入資料表) (請參考投影片) (或詳參: https://dev.mysql.com/doc/workbench/en/wb-table-editor.html)

CREATE TABLE `practice`.`customer` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(15) NULL,
  `address` VARCHAR(45) NULL,
  `weight` INT NULL,
  PRIMARY KEY (`id`));

提供REST services

Spring framework提供了RepositoryRestResource讓這件事變得非常簡單。只要寫一個CustomerDAO.java,跟CrudRepository的做法類似 (詳參: Spring JPA),只是加上了RepositoryRestResource。

package com.example.demo.dao;

import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.repository.CrudRepository;

import com.example.demo.entity.Customer;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerDAO extends CrudRepository<Customer, Long> {

}

可以使用PagingAndSortingRepository,當資料量大的時候,可以排序,也可以看特定的頁的資料。

package com.example.demo.dao;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import com.example.demo.entity.Customer;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerDAO extends PagingAndSortingRepository<Customer, Long> {

}

Customer.java裡利用@Entity告訴JPA這是個Entity類別,JPA會自動連接到類別名稱對應的資料表(customer)。另外,並以@Id指定一個欄位為資料表對應的主鍵(primary key),如果這個欄位的內容是自動產生,則必須加上@GeneratedValue(strategy=GenerationType.IDENTITY) (詳參: http://www.thoughts-on-java.org/jpa-generate-primary-keys/ )。**在Hibernate 5,設為AUTO會使用一個資料表來產生序號,所以,請改為IDENTITY或SEQUENCE (詳參: Migration from Hibernate 4 to 5)

package com.example.demo.entity;

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 = "customer")
public class Customer {
  @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;
 private String name;

 @Column(name = "address")
 private String address;
 private int weight;

 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 String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public int getWeight() {
  return weight;
 }

 public void setWeight(int weight) {
  this.weight = weight;
 }

}

ㄧ般而言,我們是利用RESTful web services,與其他的web site或手機交換資料。所以,下面的範例可以想像成去另外一個網站(雖然目前的url是自己)取得資料。

http://localhost:8080/customer/1 的內容類似:

{
  "name" : "Ben",
  "address" : "新北市新莊區中正路510號",
  "weight" : 60,
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/customer/1"
    },
    "customer" : {
      "href" : "http://localhost:8080/customer/1"
    }
  }
}

可以利用postman去進行資料的CRUD。(詳參: Postman - 測試Web Service的工具, Spring MVC RESTFul Web Service CRUD Example: Deploy and Test Spring MVC RESTFul API using Postman)

Create是利用HTTP POST

Read是利用HTTP GET

Update是利用HTTP PUT

Delete是利用HTTP DELETE

也可以用以下的jQuery去得到id = 1(如果存在的話)的customer資料。jQuery的語法請詳參jQuery

<!DOCTYPE html>
<html>
<head>
<title>Hello jQuery</title>
<script
  src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
 $(document).ready(function() {
  $.ajax({
   url : "http://localhost:8080/customer/1",
   success : function(data) {
    $('.customer-name').append(data.name);
    $('.customer-address').append(data.address);
   },
   error: function(){
    $('.customer-name').append("**Not Available**");
    $('.customer-address').append("**Not Available**");
   }
  });
 });
</script>
</head>

<body>
 <div>
  <p class="customer-name">The Name is</p>
  <p class="customer-address">The Address is</p>
 </div>
</body>
</html>

http://localhost:8080/customer 的內容類似:

{
  "_embedded" : {
    "customer" : [ {
      "name" : "Ben",
      "address" : "新北市新莊區中正路510號",
      "weight" : 60,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/customer/1"
        },
        "customer" : {
          "href" : "http://localhost:8080/customer/1"
        }
      }
    }, {
      "name" : "Cathy",
      "address" : "台北市仁愛路1號",
      "weight" : 65,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/customer/2"
        },
        "customer" : {
          "href" : "http://localhost:8080/customer/2"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/customer{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/customer"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

以下的範例是讀取上面的資料,並將資料放到表格中。jQuery的語法請詳參jQuery

<!DOCTYPE html>
<html>
<head>
<title>Hello jQuery</title>
<script
  src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
 $(document).ready(function() {
  $.ajax({
   url : "http://localhost:8080/customer",
   success : function(data) {
    $.each(data._embedded.customer, function(i, item) {
     $('#customer_tbl tbody').append("<tr><td>");
     $('#customer_tbl tbody').append(item.name);
     $('#customer_tbl tbody').append("</td><td>");
     $('#customer_tbl tbody').append(item.address);
     $('#customer_tbl tbody').append("</td></tr>");
    })
   }
  });
 });
</script>
</head>

<body>
 <table id="customer_tbl">
  <thead>
   <tr>
    <th>Name</th>
    <th>Address</th>
   </tr>
  </thead>
  <tbody>
  </tbody>
 </table>
</body>
</html>

參考資料