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

★ RESTful服务

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

复制代码
后端应用对外暴露RESTful服务,前端应用则通过RESTful服务与后端应用交互。

后端应用  RESTful接口   <------------------> 前端

★ 基于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?参数    -(删除数据) 删除符合指定参数的图书

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

复制代码
   HttpEntity    只能额外地指定响应头,不支持指定响应码。
       ↑
 ResponseEntity:  可额外指定响应的响应头、响应码(HttpStatus代表)

 ResponseEntity 继承 HttpEntity    

代码演示

总结:就只是前端用 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

java 复制代码
@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;
    }
}

BookController

java 复制代码
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);
    }

}

BookService

java 复制代码
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);

}

BookServiceImpl

java 复制代码
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;
    }
}
相关推荐
wuyikeer10 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor35610 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor35610 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer11 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP11 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)12 小时前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang
开心就好202512 小时前
使用Wireshark进行TCP数据包抓包分析:三次握手与四次挥手详解
后端·ios
用户44193950548712 小时前
OpenClaw服务器部署保姆级教程
后端
zdl68612 小时前
springboot集成onlyoffice(部署+开发)
java·spring boot·后端
Soofjan12 小时前
sync.Mutex讲解
后端