使用 Spring Boot 構建 RESTful Web API ...
1. 使用 Idea 創建 Spring Initializer 項目
在創建項目的對話框中添加 Web 和 Lombok,或者建立項目後在 pom.xml
中添加依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2. 使用註解構建 RESTful API
此處沒有使用資料庫,用 ArrayList 作為操作對象。
創建一個實體類,作為 API 操作的對象
package top.cloudli.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Character {
private int id;
private String name;
private String racial;
private String[] ability;
}
這裡使用了 lombok,省去了編寫 Getter、Setter 以及構造函數,添加相應的註解後 lombok 會自動生成。
創建 Controller,實現 RESTful API
@RestController
相當於 @Controller
和 @ResponseBody
的組合,使用該註解後,MIME 預設為 application/json
。
@GetMapping
相當於 @RequestMapping(method = {RequestMethod.GET})
,其他註解類似。
package top.cloudli.demo.controller;
import org.springframework.web.bind.annotation.*;
import top.cloudli.demo.model.Character;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* CRUD for Character
*/
@RestController
@RequestMapping(path = "/character")
public class CharacterController {
private ArrayList<Character> characters = (ArrayList<Character>) Stream.of(
new Character(1, "羅小黑", "妖精", new String[]{"空間系-傳送", "空間系-領域"}),
new Character(2, "羅小白", "人類", null)
).collect(Collectors.toList());
/**
* 獲取所有 Character
* @return All Characters
*/
@GetMapping()
public List<Character> getCharacters() {
return characters;
}
/**
* 根據 id 獲取 Character
* @param id Id of Character
* @return Character
*/
@GetMapping(path = "{id}")
public Character getCharacter(@PathVariable int id) {
return characters.stream()
.filter(character -> character.getId() == id)
.findAny()
.orElse(null);
}
/**
* 更新 Character
* @param character Changed Character
* @return Updated Character
*/
@PutMapping()
public Character alterCharacter(@RequestBody Character character) {
AtomicBoolean found = new AtomicBoolean(false);
characters.replaceAll(c -> {
if (c.getId() == character.getId()) {
found.set(true);
return character;
} else return c;
});
return found.get() ? character : null;
}
/**
* 添加 Character
* @param character New Character
* @return Inserted Character
*/
@PostMapping()
public Character addCharacter(@RequestBody Character character) {
return characters.add(character) ? character : null;
}
/**
* 刪除 Character
* @param id Id of Character
* @return Id of Character deleted
*/
@DeleteMapping(path = "{id}")
public int deleteCharacter(@PathVariable int id) {
return characters.removeIf(character -> character.getId() == id) ? id : -1;
}
}
3. 運行項目,訪問 API
URL | 方法 | 操作 |
---|---|---|
/character | GET | 獲取所有的 Character |
/character/id | GET | 獲取指定 id 的 Character |
/character | PUT | 修改 Character,傳遞修改後的完整對象 |
/character/id | DELETE | 刪除指定 id 的 Character |
如果使用 ?id=xxx
的方式,可以將註解中的 path
參數去掉。
發送 GET
請求到 http://localhost:8080/character
:
[
{
"id": 1,
"name": "羅小黑",
"racial": "妖精",
"ability": [
"空間系-傳送",
"空間系-領域"
]
},
{
"id": 2,
"name": "羅小白",
"racial": "人類",
"ability": null
}
]
發送 GET
請求到 http://localhost:8080/character/1
:
{
"id": 1,
"name": "羅小黑",
"racial": "妖精",
"ability": [
"空間系-傳送",
"空間系-領域"
]
}
DELETE
請求與上面的 GET
一樣,成功後指定 id 的 Character 將被刪除,返回刪除的 id。
發送 PUT
請求到 `http://localhost:8080/character
,向 Header 添加 Content-Type:application/json
,Body 部分為 修改後的完整數據:
{
"id": 1,
"name": "小黑",
"racial": "妖精",
"ability": [
"空間系-傳送"
]
}
成功後將返回與上面一樣的 JSON 數據。
POST
請求與前面的 PUT
一樣,成功後返回提交的數據。