目录
前言:
restful是一种风格,并不是一种 标准,使用它可以更好的创建分布式架构;restful风格中使用名词定位资源,并使用HTTP协议里的动词(GET、POST、PUT、DELETE)来实现资源的增删改查操作。
1、RESTFUL 原则
1.1、资源与URI
URL,URI
URI:全称为Uniform Resource Identifier,即统一资源标志符
URI是一个用来标识抽象或物理资源的紧凑字符串,通过这个标识可以访问一个唯一的资源。
URL:全称为Universal Resource Locator,即统一资源定位符
URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。
资源
互联网中资源多种多样,我门所知的视频,图片,文字,音频,html等都是资源的表述,资源通过URI进行唯一标识,每一个URI代表一种资源,所以我们能通过检索查询到特定资源。
1.2、统一资源接口
RESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。
如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。而GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。
- get-安全且幂等
- post-不安全不幂等
- put-不安全且幂等
- delete-不安全且幂等
1.3、资源的表述
客户端获取的只是资源的表述而已。 资源在外界的具体呈现,可以有多种表述(或成为表现、表示)形式,在客户端和服务端之间传送的也是资源的表述,而不是资源本身。 例如文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来。
1.4、状态
状态可分为应用状态和资源状态,应用状态由客户端维护,资源状态由服务器端维护。
有状态和无状态
有状态
是指状态信息是由服务器端负责,例如用户通过提交的cookie信息查找对应服务器端的session信息,由服务器确定用户状态(如cookie和session来维持登录)。
无状态
当请求端提出请求时,状态信息有客户客户端负责,请求本身包含了响应端为相应这一请求所需的全部信息关联的用户交互操作保留的某种公共信息,例如JWT风格,使用token来维持状态信息。
状态转移(应用状态化改变资源状态化)
例如打开一个淘宝主页面并点击某个商品,按照常理它会跳转到商品详情页面,可实际上它跳转到了登录页面。
这是因为服务器不能识别客户端状态,当登录后,服务器端的session就可以判断出是哪个用户,并响应资源。
状态转移可以理解为:根据用户端的状态改变资源状态
2、restful风格接口书写方式
- 使用名词表示资源
- 使用单复数表示单个和多个资源
- 使用正斜杠(/)表示层次关系
- 使用连字符( - )来提高URI的可读性
- 在URI中使用小写字母
- 在URI中使用小写字母
书写格式:标准的HTTP方法+URI
GET - /users | 返回用户列表 |
GET- /users/id | 返回特定用户 |
DELETE- /users/id | 删除指定用户 |
POST- /users | 添加用户 |
PUT -/users/id | 更新指定用户 |
3、restful风格的实践
本实践基于springboot+mybatisplugs+maven
3.1、项目结构
3.2、创建项目
使用官方推荐方式:Spring Initializr
我的Group为:com.duhong.learning
回车下载压缩包,再导入到idea中
3.3、配置
3.3.1、添加mybatis plugs依赖
在maven 库(https://mvnrepository.com/)中查询mybatis plugs依赖
pom.xml中添加依赖
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
3.3.2、 添加热部署
1、pom.xml配置
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--打开开关-->
<configuration>
<fork>true</fork>
</configuration>
</plugin>
2、配置设置
3.3.3、配置application.yml
说明:要先删除application.properties减少干扰,yml文件的优先级大于properties文件,但都生效,后面properties文件会覆盖yml文件。
#配置服务端口
server:
port: 80
#配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db3
username: root
password: 3237never
#配置mybatis plugs插件,设置数据库id自增,默认为ASSIGN_ID,使用id自增,简便配置
mybatis-plus:
global-config:
db-config:
id-type: auto
3.4、编码
持久层
package com.duhong.learning.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
//lombok,一个java类库,提供了一组注解,简化了pojo实体类开发
//@AllArgsConstructor
@Data//相当于getter,setter,tostring
@TableName(value = "account")
public class User {
private Integer id;
private String name;
private Double balance;
}
数据操作层
package com.duhong.learning.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.duhong.learning.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
//@Mapper
//public interface UserDao {
// @Select("select * from account where id=#{id}")
// User getById(Integer id);
//}
@Mapper
public interface UserDao extends BaseMapper<User> {
}
服务接口层
package com.duhong.learning.service;
import com.duhong.learning.domain.User;
import java.util.List;
public interface UserService {
public User selectById(Integer id);
public List<User> selectList();
public Integer deleteById(Integer id);
public Integer insert(User user);
public Integer updateById(User user,Integer id);
}
服务层
package com.duhong.learning.service.impl;
import com.duhong.learning.dao.UserDao;
import com.duhong.learning.domain.User;
import com.duhong.learning.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private User user;
@Autowired
UserDao userDao;
@Override
public User selectById(Integer id) {
try{
user=null;
user=userDao.selectById(id);
}catch (Exception e){
System.out.println(e.getMessage());
}
return user;
}
@Override
public List<User> selectList() {
List<User> users=userDao.selectList(null);
// for(User item :users){
// System.out.println(item.toString());
// }
return users;
}
//删除,添加,更新指定用户,返回执行条数,可以用返回值查看是否操作成功
@Override
public Integer deleteById(Integer id) {
Integer sign=0;
try {
sign=userDao.deleteById(id);
}catch (Exception e){
System.out.println(e.getMessage());
}
return sign;
}
@Override
public Integer insert(User user) {
Integer sign=0;
try {
user.setName(user.getName());
user.setBalance(user.getBalance());
sign=userDao.insert(user);
}catch (Exception e){
System.out.println(e.getMessage());
}
return sign;
}
@Override
public Integer updateById(User user, Integer id) {
Integer sign=0;
try {
user.setId(id);
user.setName(user.getName());
user.setBalance(user.getBalance());
sign=userDao.updateById(user);
}catch (Exception e){
System.out.println(e.getMessage());
}
return sign;
}
}
控制层
package com.duhong.learning.controller;
import com.duhong.learning.domain.User;
import com.duhong.learning.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//Restful风格
@RestController
public class UserController {
@Autowired
UserServiceImpl userService;
@RequestMapping(value = "/users",method = RequestMethod.GET)
List<User> showAll(){
return userService.selectList();
}
@RequestMapping(value = "/users/{id}",method = RequestMethod.GET)
User showById(@PathVariable Integer id){
return userService.selectById(id);
}
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
Integer deleteById(@PathVariable Integer id){
return userService.deleteById(id);
}
@PutMapping("/users/{id}")//换种方式,等效于@RequestMapping(value = "/users/{id}",method = RequestMethod.PUT)
Integer updataById(@RequestBody User user,@PathVariable Integer id){
return userService.updateById(user,id);
}
@PostMapping("/users")//接受User对象参数
Integer add(@RequestBody User user){
return userService.insert(user);
}
}
使用postman进行测试
推荐vscode中使用Postcode插件,相当方便
查询所有
添加数据
根据id查询指定用户
更新指定用户
删除指定用户
感谢你阅读到最后~
期待你的关注、收藏、评论、点赞~
愿我们一起变强