Spring Boot学习随笔- RestFul API(@RestController、@RequestBody、@PathVariable),使用ResponseEntity+HttpStatus作为返回值

发布时间 2023-12-26 18:45:46作者: 扬眉剑出鞘

学习视频:【编程不良人】2021年SpringBoot最新最全教程

第十六章、RestFul API

  • 什么是REST

    REST 全称是 Resource Representational State Transfer,中文意思是表述性状态转移,它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。他在论文中表示:我这篇文章的目的就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条条件和原则,“如果一个架构复合REST的约束条件和原则,我们就称它为RESTful架构”

RestFul:是一种以网络为基础构架一种架构一种架构风格,一个符合Rest设计原则和约束成这个架构为RestFul。

REST本身并没有创造新的技术、组件和服务、而隐藏在RESTful背后的理念就是使用web的现有特征和能力,更好地使用现有web标准中的一些准则和约束。

  • RestFul遵循的架构约束

    1. 客户端-服务器架构:由客户端、服务器和资源组成,通过HTTP管理请求。
    2. 无状态的客户端-服务器通信:每个请求都是独立的,不会在请求之间保存客户端信息。
    3. 可缓存的数据:通过缓存数据来优化客户端-服务器交互。
    4. 统一的接口:信息以标准形式传输,包括资源的标识和表示之间的分离,以及自描述的消息返回给客户端。
  • 总结

    RestFul是一种架构风格,不是标准,只是提供了一组设计原则和约束条件,它主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁、更有层次,更易于实现缓存等机制。

  • URL定义

    • 资源:互联网所有的事务都可以称为资源:一张图片、一段文本、一条记录…..
    • 资源操作:使用POST添加、DELETE删除,PUT修改,GET查询,使用不同请求方法对资源进行操作
      • 删除 delete
      • 查询 get
      • 添加 post
      • 修改 put(修改全部字段) patch(更新部分字段)
  • 传统方式操作资源

    注意:传统的操作是没有问题的,大神认为有问题的:你每次请求的接口或者地址都是在做描述,其实完全没有这个必要,我使用了get请求,就是代表查询,使用post就是代表新增请求,我的意图很明显,完全没有必要做描述,这就是为什么有了restful。

  • 使用RESTful操作资源

    • 【GET】 /users 查询用户信息列表
    • 【GET】 /users/1001 查看某个用户信息
    • 【POST】 /users 新增用户信息
    • 【PUT】 /users/1001 更新用户信息(全部字段)
    • 【PATCH】 /users/1001 更新用户信息(部分字段)
    • 【DELETE】 /users/1001 删除用户信息

第一个RestFul风格的API

@RestController // 专用于restful风格的注解,只能返回json/Xml格式的数据
@RequestMapping("/v1/users")
public class UserController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    /**
     * 获取单个用户
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public User user(@PathVariable("id") Integer id) {
        log.info("id:{}", id);
        return new User(21, "小明", 2000.2, new Date());
    }

    /**
     * 用户列表
     * @return
     */
    @GetMapping()
    public List<User> users() {
        ArrayList<User> users = new ArrayList<>();
        users.add(new User(21, "小明", 2000.2, new Date()));
        users.add(new User(16, "小红", 3000.2, new Date()));
        return users;
    }

    /**
     * 添加用户
     * @param user
     */
    @PostMapping
    public void saveUser(@RequestBody User user) {
        log.info("用户信息:{}", user);
        //调用业务方法...
    }

    /**
     * 修改用户
     * @param user
     */
    @PutMapping("/{id}")
    public void update(@PathVariable("id") Integer id, @RequestBody User user) {
        log.info("更新用户的id:{}",id);
        log.info("修改信息:{}", user);
        //调用业务方法...
    }

    /**
     * 删除用户
     * @param id
     */
    @DeleteMapping("/{id}")
    public void delete(@PathVariable("id") Integer id) {
        log.info("id:{}",id);
    }
}

**@RestController 注解**

**@RestController** 注解则是用来创建 REST API 控制器的。在 REST API 中,通常需要返回 JSON 或 XML 格式的数据,而不是 HTML 视图。因此,@RestController 注解结合了 @Controller@ResponseBody 注解的功能,可以方便地实现 REST API 的开发。

@RequestBody 注解

@RequestBody 注解将请求体中的 JSON 数据转换为 Java 对象。

**@PathVariable注解**

这个注解用于处理RESTful API中的URL路径参数。例如**@GetMapping("/{id}")** ,我们需要使用@PathVariable注解来提取URI中的{id},并将其作为方法的参数。

@PathVariable还有一些属性可以使用:

  1. 指定路径变量的名称: 如果路径变量的名称与方法参数的名称不同,我们可以在@PathVariable注解中指定路径变量的名称。

    @GetMapping("/api/employees/{empId}")
    public String getEmployeeById(@PathVariable("empId") String id) {
        return "ID: " + id;
    }
    
    
  2. 指定默认值: 我们还可以在@PathVariable注解中指定默认值,以防路径变量未提供。

    @GetMapping("/api/employees/{id}")
    public String getEmployeeById(@PathVariable(name = "id", required = false, defaultValue = "0") String id) {
        return "ID: " + id;
    }
    
  • 如果业务逻辑还要往深一层查,比如查某个人的某个宠物,那么可以这样

    /**
     * 获取某个人的所有宠物信息
     */
    @GetMapping("/{id}/pets")
    public List<Pet> pets(@PathVariable("id") Integer id) {
        log.info("查询人的id:{}", id);
        return Arrays.asList(new Pet(2, "旺财", 2),new Pet(3,"花花",1));
    }
    
    /**
     * 获取某个人的某个宠物信息
     */
    @GetMapping("/{id}/pets/{pid}")
    public Pet pets(@PathVariable("id") Integer id,@PathVariable("pid") Integer pid) {
        log.info("查询人的id:{}", id);
    		Pet pet = new Pet(2, "旺财", 2);
        return pet;
    }
    

ResponseEntityHttpStatus

ResponseEntity代表了整个 HTTP 响应,包括状态码、头部信息和响应体。可以完全配置 HTTP 响应。ResponseEntity提供了泛型,所以我们可以使用它来代替API中的返回值

  • 示例

    //ResponseEntity springmvc中用于restful响应类,可以提供响应的状态码,以及自定义响应头信息
    // HttpStatus:springmvc提供的枚举类型类  网络状态码
    
    /**
     * 获取单个用户
     */
    @GetMapping("/{id}")
    public ResponseEntity<User> user(@PathVariable("id") Integer id) {
        log.info("id:{}", id);
        User user = new User(21, "小明", 2000.2, new Date());
        return new ResponseEntity<>(user, HttpStatus.OK);// 状态码:200
    }
    
    /**
     * 用户列表
     */
    @GetMapping()
    public ResponseEntity<List<User>> users() {
        ArrayList<User> users = new ArrayList<>();
        users.add(new User(21, "小明", 2000.2, new Date()));
        users.add(new User(16, "小红", 3000.2, new Date()));
        return new ResponseEntity<>(users,HttpStatus.OK);// 状态码:200
    }
    
    /**
     * 添加用户
     */
    @PostMapping
    public ResponseEntity<Void> saveUser(@RequestBody User user) {
        log.info("用户信息:{}", user);
        //调用业务方法...
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);//没有内容,状态码204
    }