Spring Boot 通过提供开箱即用的默认依赖或者转换来补充 Spring REST 支持. 在 Spring Boot 中编写 RESTful 服务与 SpringMVC 没有什么不同. 总而言之, 基于 Spring Boot 的 REST 服务与基于 Spring 的 REST 服务完全相同, 只是在我们引导底层应用程序的方式上有所不同.
1.REST 简短介绍
REST 代表 Representational State Transfer. 是一种架构风格, 设计风格而不是标准, 可用于设计 web 服务, 可以从各种客户端使用.
基于 REST 的基本设计, 其是根据一组动词来控制的操作
创建操作: 应使用 HTTP POST
查询操作: 应使用 HTTP GET
更新操作: 应使用 HTTP PUT
删除操作: 应使用 HTTP DELETE
作为 REST 服务开发人员或客户端, 您应该遵守上述标准.
2. 准备工作
项目的环境工具
- SpringBoot 2.0.1.RELEASE
- Gradle 4.7
- IDEA 2018.2
- MySQL5.7
项目结构图
3. 开始
下面基于一种方式讲解 Restful
- package com.example.controller;
- import com.example.beans.PageResultBean;
- import com.example.beans.ResultBean;
- import com.example.entity.User;
- import com.example.service.UserService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.Web.bind.annotation.PathVariable;
- import org.springframework.Web.bind.annotation.RequestMapping;
- import org.springframework.Web.bind.annotation.RequestMethod;
- import org.springframework.Web.bind.annotation.RestController;
- import java.util.List;
- @RestController
- @RequestMapping("/user")
- public class UserControllerAPI {
- private final UserService userService;
- @Autowired
- public UserControllerAPI(UserService userService) {
- this.userService = userService;
- }
- @RequestMapping(value = "/api", method = RequestMethod.GET)
- public PageResultBean<List<User>> getUserAll(PageResultBean page) {
- return new PageResultBean<>(userService.getUserAll(page.getPageNo(), page.getPageSize()));
- }
- @RequestMapping(value = "/api/{id}", method = RequestMethod.GET)
- public ResultBean<User> getUserByPrimaryKey(@PathVariable("id") Integer id) {
- return new ResultBean<>(userService.selectByPrimaryKey(id));
- }
- @RequestMapping(value = "/api/{id}", method = RequestMethod.PUT)
- public ResultBean<Integer> updateUserByPrimaryKey(@PathVariable("id") Integer id,User user) {
- user.setId(id);
- return new ResultBean<>(userService.updateByPrimaryKeySelective(user));
- }
- @RequestMapping(value = "/api/{id}", method = RequestMethod.DELETE)
- public ResultBean<String> deletePrimaryKey(@PathVariable("id") Integer id) {
- return new ResultBean<>(userService.deleteByPrimaryKey(id));
- }
- @RequestMapping(value = "/api", method = RequestMethod.POST)
- public ResultBean<Integer> deletePrimaryKey(User user) {
- return new ResultBean<>(userService.insertSelective(user));
- }
- }
对于 / user/API HTTP GET 来请求获取全部用户
对于 / user/API HTTP POST 来创建用户
对于 / user/API/1 HTTP GET 请求来获取 id 为 1 的用户
对于 / user/API/1 HTTP PUT 请求来更新
对于 / user/API/1 HTTP DELETE 请求来删除 id 为 1 的用户
HTTP GET 请求 / user/API 查询全部
URL:http://localhost:8080/user/API
HTTP GET 请求 / user/API/65 跟据 id 查询
URL:http://localhost:8080/user/API/65
HTTP POST 请求 / user/API 创建用户
URL:http://localhost:8080/user/API
HTTP PUT 请求 / user/API/65 来更新用户信息
URL:http://localhost:8080/user/API/65
HTTP DELETE 请求 / user/API/85 来删除 id 为 85 的用户
URL:http://localhost:8080/user/API/85
4. 业务层及 dao 层代码
UserService.java 接口
- package com.example.service;
- import com.example.entity.User;
- import java.util.List;
- public interface UserService {
- /**
- * 删除
- * @param id
- * @return
- */
- String deleteByPrimaryKey(Integer id);
- /**
- * 创建
- * @param record
- * @return
- */
- int insertSelective(User record);
- /**
- * 单个查询
- * @param id
- * @return
- */
- User selectByPrimaryKey(Integer id);
- /**
- * 更新
- * @param record
- * @return
- */
- int updateByPrimaryKeySelective(User record);
- /**
- * 查询全部
- * @return
- */
- List<User> getUserAll(Integer pageNum, Integer pageSize);
- }
UserServiceImpl.java
- package com.example.service.impl;
- import com.example.dao.UserMapper;
- import com.example.entity.User;
- import com.example.service.UserService;
- import com.GitHub.pagehelper.PageHelper;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.List;
- @Service
- public class UserServiceImpl implements UserService {
- private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
- private final UserMapper userMapper;
- @Autowired(required = false)
- public UserServiceImpl(UserMapper userMapper) {
- this.userMapper = userMapper;
- }
- /**
- * 删除
- *
- * @param id
- * @return
- */
- @Transactional
- @Override
- public String deleteByPrimaryKey(Integer id) {
- logger.info("UserServiceImpl deleteByPrimaryKey id =>" + id);
- User user = userMapper.selectByPrimaryKey(id);
- String result;
- if (user == null) {
- result = "用户 ID[" + id + "] 找不到!";
- } else {
- result = String.valueOf(userMapper.deleteByPrimaryKey(id));
- }
- return result;
- }
- /**
- * 创建
- *
- * @param record
- * @return
- */
- @Transactional
- @Override
- public int insertSelective(User record) {
- logger.info("UserServiceImpl insertSelective record=>"+record.toString());
- return userMapper.insertSelective(record);
- }
- /**
- * 单个查询
- *
- * @param id
- * @return
- */
- @Override
- public User selectByPrimaryKey(Integer id) {
- logger.info("UserServiceImpl selectByPrimaryKey id=>"+id);
- return userMapper.selectByPrimaryKey(id);
- }
- /**
- * 更新
- *
- * @param record
- * @return
- */
- @Override
- public int updateByPrimaryKeySelective(User record) {
- logger.info("UserServiceImpl updateByPrimaryKeySelective record=>"+record.toString());
- return userMapper.updateByPrimaryKeySelective(record);
- }
- /**
- * 查询全部
- *
- * @param pageNum
- * @param pageSize
- * @return
- */
- @Override
- public List<User> getUserAll(Integer pageNum, Integer pageSize) {
- logger.info("UserServiceImpl getUserAll pageNum=>"+pageNum+"=>pageSize=>"+pageSize);
- PageHelper.startPage(pageNum,pageSize);
- List<User> userList = userMapper.getUserAll();
- logger.info("UserServiceImpl getUserAll userList"+userList.size());
- return userList;
- }
- }
UserMapper.java
- package com.example.dao;
- import com.example.entity.User;
- import java.util.List;
- public interface UserMapper {
- int deleteByPrimaryKey(Integer id);
- int insert(User record);
- int insertSelective(User record);
- User selectByPrimaryKey(Integer id);
- int updateByPrimaryKeySelective(User record);
- int updateByPrimaryKey(User record);
- List<User> getUserAll();
- }
PageResultBean 和 ResultBean 的代码在 GitHub
https://github.com/cuifuan/springboot-demo
实体层和 mapper.xml 代码都是可以自动生成的, 教程导航:
Spring 全家桶系列 --SpringBoot 与 Mybatis 结合
4. 理解 RESTful
通过上面的编码, 如果你已经走通了上面的代码, 相信你已经对 REST 有了大致的掌握, 时今当下的前端 Client 层出不穷, 后端接口或许来自不同平台, 这时候需要请求一批接口, 而 RESTful 风格的 API, 使人从请求方式和地址一看就知道是要做什么操作, 根据返回 code 状态就知道结果如何
使用 RESTful 直接带来的便利:
之前的接口
删除 /user/delete
添加 /user/create
单个查询 /user/queryById
查询全部 /user/queryAll
更新 /user/update
采用 RESTful 设计 API 之后 /user/API 一个 URL 地址解决, 再也不用跟前端废舌头了, 同时 GET 请求是幂等的, 什么是幂等? 简单通俗的说就是多次请求返回的效果都是相同的, 例如 GET 去请求一个资源, 无论请求多少次, 都不会对数据造成创建修改等操作, PUT 用来更新数据也是, 无论执行多次的都是最终一样的效果
问题: 使用 PUT 改变学生年龄并且这样做 10 次和做了一次, 学生的年龄是相同的, 是幂等的, 那么如果 POST 做相同操作, 那么它是如何不是幂等的?
答: 因为 POST 请求会在服务端创建与请求次数相同的服务, 假如服务端每次请求服务会存在一个密钥, 那么这个 POST 请求就可能不是幂等的, 也或许是幂等的, 所以 POST 不是幂等的.
因为 PUT 请求 URL 到客户端定义的 URL 处完整地创建或替换资源, 所以 PUT 是幂等的. DELETE 请求也是幂等的, 用来删除操作, 其实 REST 就是相当于一个风格规范.
注意了, GET 请求请不要用在 delete 操作上, 你要问我为啥不行, 你偏要那么做, 其实, 整个 CRUD 操作你也都可以用 GET 来完成, 哈哈, 这个只是一个开发的设计风格.
来源: https://www.cnblogs.com/javazhiyin/p/10005794.html