★ 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
@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
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 代表 200return 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 代表返回的状态码为 201return 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
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
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查看图书@Overridepublic Book getBookById(Integer id){if (id != null){Book book = bookDB.get(id);if (book!=null){return book;}}throw new RuntimeException("根据id查看图书失败!");}//查看所有图书@Overridepublic List<Book> getAllBooks(){//获取map中的所有数据Collection<Book> mapBooks = bookDB.values();//强转List<Book> books = new ArrayList<>(mapBooks);return books;}//添加/修改图书@Overridepublic Book addOrUpdateBook(Book book){if (book.getId() != null){//修改//map的key是唯一的,所以map里面有这个key的话,直接把原来的value覆盖掉bookDB.put(book.getId(),book);return book;}else {//新增//为新增的图书设置idbook.setId(nextId);//book添加完之后,这个id才会自增bookDB.put(nextId++,book);return book;}}//根据id删除图书@Overridepublic Book deleteBookById(Integer id){Book book = bookDB.remove(id);return book;}
}