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}]