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
一样,成功后返回提交的数据。