• 56、springboot ------ RESTful服务及RESTful接口设计


    ★ RESTful服务

    RESTful服务是“前后端分离”架构中的主要功能:

    后端应用对外暴露RESTful服务,前端应用则通过RESTful服务与后端应用交互。
    
    后端应用  RESTful接口   <------------------> 前端
    
    • 1
    • 2
    • 3

    ★ 基于JSON的RESTful服务

    使用@RestController注解修饰控制器类,或使用@ResponseBody修饰处理方法即可。

    @RestController和@Controller的区别就在于@RestController会自动为每个处理方法都添加@ResponseBody注解。

    @RequestBody,用于修饰处理方法的参数,用于获取RESTful提交的请求数据。

    RESTful有一个约定,主要是对URL有约定
    
    比如对于一个操作图书的RESTful接口:
    
    GET  /books/{id} - (获取数据) 获取指定id的图书
    GET  /books?参数  -(获取数据) 获取符合查询参数的图书
    GET  /books        -(获取数据) 获取所有图书
    POST /books        -(添加数据) 添加图书
    PUT  /books/{id}    -(更新数据) 更新指定ID的图书
    DELETE /books/{id}    -(删除数据) 删除指定ID的图书
    DELETE /books?参数    -(删除数据) 删除符合指定参数的图书
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Restful处理方法的返回值通常都应该使用HttpEntity或ResponseEntity。

       HttpEntity    只能额外地指定响应头,不支持指定响应码。
           ↑
     ResponseEntity:  可额外指定响应的响应头、响应码(HttpStatus代表)
    
     ResponseEntity 继承 HttpEntity    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    代码演示

    总结:就只是前端用 get 、 post 、 put 、 delete 发起请求,
    后端用
    @GetMapping(前端获取数据)、PostMapping(前端推送数据)、
    PutMapping(前端修改数据)、DeleteMapping(前端删除数据)
    接收,就是 RESTful风格了。

    基础数据:
    在这里插入图片描述

    1、Get 请求, 前段根据id查看图书
    在这里插入图片描述

    2、查看所有图书,前端用get请求
    在这里插入图片描述

    3、添加图书,前端用 post 请求
    在这里插入图片描述

    4、根据id更新图书信息,前端用 put 进行请求
    在这里插入图片描述

    5、根据id删除图书,前端用delete 发起请求
    在这里插入图片描述

    总结:

    如图:三个方法的访问路径都是一样的,不同的只是请求的方式不同,一个是get,一个是put,一个是delete,这就是 restful 风格,项目会自动识别。
    在这里插入图片描述

    完整代码

    Book

    @Data
    public class Book
    {
        private Integer id;
        private String name;
        private double price;
        private String author;
    
        public Book(Integer id, String name, double price, String author)
        {
            this.id = id;
            this.name = name;
            this.price = price;
            this.author = author;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    BookController

    package cn.ljh.app.controller;
    
    
    import cn.ljh.app.domain.Book;
    import cn.ljh.app.service.BookService;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /*
     *     GET  /books/{id} - (获取数据) 获取指定id的图书
     *     GET  /books?参数  -(获取数据) 获取符合查询参数的图书
     *     GET  /books        -(获取数据) 获取所有图书
     *     POST /books        -(添加数据) 添加图书
     *     PUT  /books/{id}    -(更新数据) 更新指定ID的图书
     *     DELETE /books/{id}    -(删除数据) 删除指定ID的图书
     *     DELETE /books?参数    -(删除数据) 删除符合指定参数的图书
     *
     *  Restful处理方法的返回值通常都应该使用HttpEntity或ResponseEntity。
     *
     */
    
    @RequestMapping("/books")
    @RestController
    public class BookController
    {
        //有参构造器进行依赖注入
        private BookService bookService;
    
        public BookController(BookService bookService)
        {
            this.bookService = bookService;
        }
    
    
        //根据id查看图书
        @GetMapping("/{id}")
        public ResponseEntity<Book> viewBookById(@PathVariable Integer id)
        {
            Book book = bookService.getBookById(id);
    
            //参数1:响应数据体  参数2:需要添加的响应头,没有就给个null   参数3:响应码 , OK 代表 200
            return new ResponseEntity<>(book, null, HttpStatus.OK);
        }
    
        //查看所有图书
        @GetMapping("")
        public ResponseEntity<List<Book>> viewBooks()
        {
            List<Book> allBooks = bookService.getAllBooks();
    
            return new ResponseEntity<>(allBooks, null, HttpStatus.OK);
        }
    
        //添加图书
        @PostMapping("")
        public ResponseEntity<Book> addBook(@RequestBody Book book)
        {
            Book b = bookService.addOrUpdateBook(book);
            //HttpStatus.CREATED 代表返回的状态码为 201
            return new ResponseEntity<>(b, null, HttpStatus.CREATED);
        }
    
        //根据id更新图书信息
        @PutMapping("/{id}")
        public ResponseEntity<Book> updateBookById(@PathVariable Integer id, @RequestBody Book book)
        {
            book.setId(id);
            Book b = bookService.addOrUpdateBook(book);
    
            return new ResponseEntity<>(b, null, HttpStatus.OK);
        }
    
        //根据id删除图书
        @DeleteMapping("/{id}")
        public ResponseEntity<Book> deleteBookById(@PathVariable Integer id)
        {
            Book book = bookService.deleteBookById(id);
            return new ResponseEntity<>(book, null, HttpStatus.OK);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    BookService

    package cn.ljh.app.service;
    
    import cn.ljh.app.domain.Book;
    
    import java.util.List;
    
    public interface BookService
    {
        //根据id查看图书
        Book getBookById(Integer id);
    
        //查看所有图书
        List<Book> getAllBooks();
    
        //添加/修改图书
        Book addOrUpdateBook(Book book);
    
        //根据id删除图书
        Book deleteBookById(Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    BookServiceImpl

    package cn.ljh.app.service.impl;
    
    import cn.ljh.app.domain.Book;
    import cn.ljh.app.service.BookService;
    import org.springframework.stereotype.Service;
    
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    
    @Service
    public class BookServiceImpl implements BookService
    {
        //创建一个线程安全的map集合存数据,假设为数据库
        static Map<Integer, Book> bookDB = new ConcurrentHashMap<>();
        static int nextId = 1;
    
        //初始化数据库的数据
        static
        {
            bookDB.put(nextId, new Book(nextId++, "火影忍者", 120, "岸本"));
            bookDB.put(nextId, new Book(nextId++, "七龙珠", 121, "鸟山明"));
        }
    
    
        //根据id查看图书
        @Override
        public Book getBookById(Integer id)
        {
            if (id != null)
            {
                Book book = bookDB.get(id);
                if (book!=null){
                    return book;
                }
            }
            throw new RuntimeException("根据id查看图书失败!");
        }
    
        //查看所有图书
        @Override
        public List<Book> getAllBooks()
        {
            //获取map中的所有数据
            Collection<Book> mapBooks = bookDB.values();
            //强转
            List<Book> books = new ArrayList<>(mapBooks);
            return books;
        }
    
        //添加/修改图书
        @Override
        public Book addOrUpdateBook(Book book)
        {
            if (book.getId() != null){
                //修改
                //map的key是唯一的,所以map里面有这个key的话,直接把原来的value覆盖掉
                bookDB.put(book.getId(),book);
                return book;
            }else {
                //新增
                //为新增的图书设置id
                book.setId(nextId);
                //book添加完之后,这个id才会自增
                bookDB.put(nextId++,book);
                return book;
            }
        }
    
        //根据id删除图书
        @Override
        public Book deleteBookById(Integer id)
        {
            Book book = bookDB.remove(id);
            return book;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
  • 相关阅读:
    Ultra-Fast-Lane-Detection 制作自己的数据集并进行训练
    Kubernetes初探2
    postgres 建立连接并删除记录
    领域驱动设计(DDD):三层架构到DDD架构演化
    GCC Rust获批将被纳入主线代码库,或将于GCC 13中与大家见面
    刷爆力扣之盛最多水的容器
    easywsclient的DEMO测试
    Ubuntu开机后图像化界面消失只有命令行界面
    LeetCode in Python 48. Rotate Image/Matrix (旋转图像/矩阵)
    1 开发环境搭建与初识Vue
  • 原文地址:https://blog.csdn.net/weixin_44411039/article/details/132752126