Spring Rest Controller
Spring Rest Controller
2019/01/16
2021/10/07 (更新內容)
透過HTTP GET取得資料
REST controller是透過REST,以JSON格式與前端溝通。採用REST及JSON的好處是,前後端的開發平台就完全獨立,後端可以是Spring、PHP、.net或者python,前端也是一樣可以是是react,也可以是手機App,甚至可以透過REST及JSON與其他的伺服器交換資料。現在很多的open data的平台都是採用這樣的方式交換資料。
現在利用spring boot開發REST已經非常簡單了,先新增一個EmployeeController.java (Rest請詳參:Spring REST),內容和一般的Controller很像,只是將controller設定為RestController,回傳值就會自動轉為JSON格式。目前的資料以ArrayList變數的方式(employeeList)儲存,未來會介紹如何利用REST存取資料庫的內容。
@RestController
這裡使用到ArrayList (詳參: Java ArrayList),這邊使用到java 5.0之後的語法: 泛型(Generic),也就是定義ArrayList裡的每個物件都會是個Employee類別所產生的物件。
private ArrayList<Employee> employeeList = new ArrayList<>();
利用ArrayList的add方法,將物件加到ArrayList裡:
employeeList.add(new Employee("Arpit", "IT"));
src/main/java/com/example/demo/controller/EmployeeController.java
package com.example.demo.controller;
import java.util.ArrayList;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.Employee;
@RestController
public class EmployeeController {
private ArrayList<Employee> employeeList = new ArrayList<>();
public EmployeeController(){
employeeList.add(new Employee("Arpit", "IT"));
employeeList.add(new Employee("Sanjeev", "IT"));
employeeList.add(new Employee("Ben", "IT"));
}
@GetMapping("/employee")
public ArrayList<Employee> get() {
return employeeList;
}
}
我們依照MVC的切割原則,將類別定義放到entity裡。entity屬於model的一種。到這邊我們就可以看到MVC的切割了。這裡也用到了一些java的基本物件的概念以及最基本的封裝。簡單的說,盡量把變數設為private,利用對應的方法讓其他的程式(如:EmployeeController)可以讀寫變數 (詳參: Java Encapsulation )。
package com.example.demo.entity;
public class Employee{
private String name;
public Employee() {
}
public Employee(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
完整的程式: src/main/java/com/example/demo/entity/Employee.java
package com.example.demo.entity;
public class Employee{
private String name;
private String department;
public Employee() {
}
public Employee(final String name, final String department) {
this.name = name;
this.department = department;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
這樣就完成rest的部份了。呼叫rest的方式為:
http://localhost:8080/employee
可以看到rest controller很聰明的對應變數的名稱以及內容,產生了一個JSON內容:
[{"name":"Arpit","department":"IT"},{"name":"Sanjeev","department":"IT"},{"name":"Ben","department":"IT"}]
透過HTTP GET取得單筆資料
如果我們要取得單筆資料,就是REST通常會傳遞值
http://localhost:8080/employee/2
在這邊就利用{}來定義變數,再利用@PathVariable,將收到的變數轉換成參數,利用get取得對應的資料。
@GetMapping("/employee/{id}")
public Employee retrieveOneEmployee(@PathVariable("id") int id){
return employeeList.get(id);
}
得到的JSON內容:
{"name":"Ben","department":"IT"}
透過HTTP POST新增單筆資料
這時候要利用@RequestBody來收post送來的資料。
@PostMapping(value = "/employee")
public void addOneEmployee(@RequestBody Employee employee) {
employeeList.add(employee);
}
這時候就要利用postman,新增一個request,選擇POST,url: http://localhost:8080/employee/
Body輸入: (形式為raw / JSON (appication/json))
{ "name":"ruby", "department":"IT"}
當然,也可以寫個簡單的html form來執行post。
透過HTTP PUT修改單筆資料
這時候要利用@RequestBody來收put送來的資料。
@PutMapping("/employee/{id}")
public void editOneEmployee(@PathVariable("id") int id, @RequestBody Employee employee) {
employeeList.add(id,employee);
}
也可以使用set,兩個方法差別在於回傳的內容,使用add()不會有回傳值,使用set()會回傳新增的資料
@PutMapping("/employee/{id}")
public void editOneEmployee(@PathVariable("id") int id, @RequestBody Employee employee) {
employeeList.set(id,employee);
}
這時候就要利用postman,新增一個request,選擇PUT,url: http://localhost:8080/employee/3
Body輸入:(形式為raw / JSON (appication/json))
{ "name":"ruby", "department":"ACCT"}
透過HTTP DELETE刪除單筆資料
刪除資料可使用@PathVariable,將收到的那筆資料利用remove()刪除。
@DeleteMapping("/employee/{id}")
public void removeOneEmployee(@PathVariable("id") int id) {
employeeList.remove(id);
}
EmployeeController.java
package com.example.demo.controller;
import java.util.ArrayList;
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.example.demo.entity.Employee;
@RestController
public class EmployeeController {
private ArrayList<Employee> employeeList = new ArrayList<>();
public EmployeeController(){
employeeList.add(new Employee("Arpit", "IT"));
employeeList.add(new Employee("Sanjeev", "IT"));
employeeList.add(new Employee("Ben", "IT"));
}
@GetMapping("/employee")
public ArrayList<Employee> get() {
return employeeList;
}
@GetMapping("/employee/{id}")
public Employee retrieveOneEmployee(@PathVariable("id") int id){
return employeeList.get(id);
}
@PostMapping("/employee")
public void addOneEmployee(@RequestBody Employee employee) {
employeeList.add(employee);
}
@PutMapping("/employee/{id}")
public void editOneEmployee(@PathVariable("id") int id, @RequestBody Employee employee) {
employeeList.set(id, employee);
}
@DeleteMapping("/employee/{id}")
public void removeOneEmployee(@PathVariable("id") int id) {
employeeList.remove(id);
}
}
** 作業 **
參考範例,寫一個rest controller,這個rest controller可以對產品資訊進行CRUD:
產品描述 / desc (String)
價格 / price (int)
產品類型 / category (String) (個人電腦、筆記型電腦、平板電腦、智慧型手機)
庫存量 / inventory (int)
安全存量 / safetyStock (int)
產生的JSON內容:
[{"desc":"iPhone 11","price":20000, "category":"智慧型手機", "inventory":20, "safetyStock":10},{"desc":"iPhone 11 pro","price":25000, "category":"智慧型手機", "inventory":10, "safetyStock":5},{"desc":"iPhone X","price":18000, "category":"智慧型手機", "inventory":3, "safetyStock":5}]