feat:增加网络编程博客
This commit is contained in:
@@ -51,7 +51,8 @@ export default withMermaid({
|
|||||||
{ text: 'Spring MVC简介', link: '/Web-Backend/SpringBoot/SpringMVC' },
|
{ text: 'Spring MVC简介', link: '/Web-Backend/SpringBoot/SpringMVC' },
|
||||||
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
||||||
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
||||||
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' }
|
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' },
|
||||||
|
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,7 @@ export default withMermaid({
|
|||||||
{ text: 'Flyway简单使用', link: '/Web-Backend/Others/Flyway' },
|
{ text: 'Flyway简单使用', link: '/Web-Backend/Others/Flyway' },
|
||||||
{ text: 'MyBatis简介和使用', link: '/Web-Backend/Others/MyBatis' },
|
{ text: 'MyBatis简介和使用', link: '/Web-Backend/Others/MyBatis' },
|
||||||
{ text: 'RustFS简介和使用', link: '/Web-Backend/Others/RustFS' },
|
{ text: 'RustFS简介和使用', link: '/Web-Backend/Others/RustFS' },
|
||||||
{ text: 'JsonView和MapStruct使用', link: '/Web-Backend/Others/JsonView-MapStruct' },
|
{ text: '网络编程简介', link: '/Web-Backend/Others/Netword-Program' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -123,7 +124,8 @@ export default withMermaid({
|
|||||||
{ text: 'Spring MVC简介', link: '/Web-Backend/SpringBoot/SpringMVC' },
|
{ text: 'Spring MVC简介', link: '/Web-Backend/SpringBoot/SpringMVC' },
|
||||||
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
||||||
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
||||||
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' }
|
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' },
|
||||||
|
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ text: 'FastAPI',
|
{ text: 'FastAPI',
|
||||||
@@ -138,7 +140,7 @@ export default withMermaid({
|
|||||||
{ text: 'Flyway简单使用', link: '/Web-Backend/Others/Flyway' },
|
{ text: 'Flyway简单使用', link: '/Web-Backend/Others/Flyway' },
|
||||||
{ text: 'MyBatis简介和使用', link: '/Web-Backend/Others/MyBatis' },
|
{ text: 'MyBatis简介和使用', link: '/Web-Backend/Others/MyBatis' },
|
||||||
{ text: 'RustFS简介和使用', link: '/Web-Backend/Others/RustFS' },
|
{ text: 'RustFS简介和使用', link: '/Web-Backend/Others/RustFS' },
|
||||||
{ text: 'JsonView和MapStruct使用', link: '/Web-Backend/Others/JsonView-MapStruct' },
|
{ text: '网络编程简介', link: '/Web-Backend/Others/Netword-Program' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
244
docs/Web-Backend/Others/Netword-Program.md
Normal file
244
docs/Web-Backend/Others/Netword-Program.md
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
# TCP
|
||||||
|
## 定义
|
||||||
|
  TCP(Transmission Control Protocol,传输控制协议)是互联网核心的面向连接、可靠、字节流的传输层协议,工作在 OSI 模型的传输层(TCP/IP 模型的传输层),基于 IP 协议提供端到端的可靠数据传输服务。它是 HTTP、HTTPS、WebSocket、MQTT 等应用层协议的底层依赖,核心目标是解决 IP 协议 “无连接、不可靠、无顺序” 的缺陷,确保数据在不可靠的网络中准确、完整、有序地传输。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
### 面向连接
|
||||||
|
  通信前必须完成「三次握手」建立连接,通信后通过「四次挥手」释放连接:
|
||||||
|
- 三次握手:客户端发 SYN → 服务器回 SYN+ACK → 客户端发 ACK(确保双方收发能力正常);
|
||||||
|
- 四次挥手:客户端发 FIN → 服务器回 ACK → 服务器发 FIN → 客户端回 ACK(确保数据传输完毕)。
|
||||||
|
|
||||||
|
### 可靠传输
|
||||||
|
- 序号与确认号:每个字节都有序号,接收方收到后回复确认号,未收到则发送方重传;
|
||||||
|
- 超时重传:发送方未在规定时间收到确认,自动重传数据;
|
||||||
|
- 流量控制:通过滑动窗口机制,防止发送方发送过快导致接收方缓冲区溢出;
|
||||||
|
- 拥塞控制:通过慢启动、拥塞避免等算法,适应网络带宽变化。
|
||||||
|
|
||||||
|
### 面向字节流
|
||||||
|
  TCP 将应用层数据视为连续的字节流,不保留应用层数据的边界(与 UDP 的 “数据报” 模式不同):
|
||||||
|
- 发送方:应用层数据被拆分为 TCP 报文段(Segment)发送,拆分规则由 TCP 协议决定(如 MSS 限制)。
|
||||||
|
- 接收方:将收到的报文段按顺序重组为完整的字节流,再交给应用层,确保数据顺序与发送时一致。
|
||||||
|
|
||||||
|
### 有序传输
|
||||||
|
  TCP 报文段头部包含 “序号(Sequence Number)” 和 “确认号(Acknowledgment Number)”:
|
||||||
|
- 序号(SN):标识发送方当前发送的字节流位置(如序号为 100 表示当前报文段的第一个字节是整个字节流的第 100 字节)。
|
||||||
|
- 确认号(ACK):标识接收方期望下次接收的字节流位置(如确认号为 200 表示已正确接收前 199 字节,下次需从 200 字节开始接收)。
|
||||||
|
- 接收方通过序号排序报文段,丢弃重复报文,确保按发送顺序交付数据。
|
||||||
|
|
||||||
|
### 全双工通信
|
||||||
|
  TCP 连接是双向的,双方可同时发送和接收数据,无需等待对方结束发送:
|
||||||
|
- 每个方向都有独立的发送缓冲区和接收缓冲区,以及独立的滑动窗口用于流量控制。
|
||||||
|
- 示例:客户端发送数据的同时,服务器可同步向客户端返回响应,无需等待客户端发送完毕。
|
||||||
|
|
||||||
|
## 优缺点
|
||||||
|
  优点:
|
||||||
|
1. 可靠、有序、无丢包
|
||||||
|
2. 支持流量 / 拥塞控制
|
||||||
|
3. 适用于大数据传输
|
||||||
|
|
||||||
|
  缺点:
|
||||||
|
1. 连接建立 / 释放开销大
|
||||||
|
2. 头部开销大(20-60 字节)
|
||||||
|
3. 不适合实时性要求极高的场景(如直播低延迟)
|
||||||
|
|
||||||
|
# HTTP
|
||||||
|
## 定义
|
||||||
|
  HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网的核心协议之一,用于客户端(如浏览器、App)与服务器之间的通信,是万维网(WWW)数据交换的基础。它定义了请求 / 响应的格式、传输规则和状态码等核心机制,支持从简单文本到复杂多媒体(图片、视频、文件)的传输,也是现代 Web 应用的底层通信标准。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
### 请求 - 响应模式
|
||||||
|
  通信由客户端主动发起请求,服务器接收后处理并返回响应,不存在服务器主动向客户端推送数据的情况(HTTP/2 引入 Server Push 扩展,可主动推送关联资源)。
|
||||||
|
  一次完整通信流程:客户端建立连接 → 发送请求 → 服务器处理 → 返回响应 → 连接关闭(HTTP/1.1 默认开启长连接 Keep-Alive)。
|
||||||
|
|
||||||
|
### 无状态
|
||||||
|
  服务器不会保存客户端的会话状态(如登录状态、浏览记录),每次请求都是独立的,服务器无法通过协议本身识别连续请求是否来自同一客户端。通过 Cookie、Session、Token(如 JWT)等机制补充状态管理。
|
||||||
|
|
||||||
|
## 版本
|
||||||
|
### HTTP/1.0(1996 年)
|
||||||
|
- 基础版本,支持 GET、POST、HEAD 三种请求方法。
|
||||||
|
- 每次请求都需要建立新的 TCP 连接(短连接),连接建立和关闭的开销大,性能较低。
|
||||||
|
- 不支持长连接、管线化请求,仅支持简单的文本传输。
|
||||||
|
|
||||||
|
### HTTP/1.1(1999 年)
|
||||||
|
- 默认开启 长连接(Keep-Alive):同一 TCP 连接可处理多个请求,减少连接开销。
|
||||||
|
- 支持 管线化请求:客户端可连续发送多个请求,无需等待前一个响应返回(部分浏览器未完全支持)。
|
||||||
|
- 新增请求方法:PUT、DELETE、OPTIONS、TRACE、CONNECT。
|
||||||
|
- 支持 chunked 编码(分块传输)、缓存控制(Cache-Control)、内容协商等核心功能。
|
||||||
|
|
||||||
|
### HTTP/2(2015 年)
|
||||||
|
  基于 SPDY 协议优化,核心目标是提升性能:
|
||||||
|
- 二进制帧传输:将请求 / 响应数据拆分为二进制帧,而非 HTTP/1.x 的文本格式,解析效率更高。
|
||||||
|
- 多路复用:同一 TCP 连接中可并发处理多个请求(通过帧的 Stream ID 区分),解决 HTTP/1.1 的 “队头阻塞” 问题。
|
||||||
|
- 服务器推送(Server Push):服务器可主动向客户端推送关联资源(如 HTML 引用的 CSS/JS),减少客户端请求次数。
|
||||||
|
- 头部压缩(HPACK):对请求头和响应头进行压缩,减少传输体积(HTTP/1.x 头部重复传输开销大)。
|
||||||
|
|
||||||
|
### HTTP/3(2022 年)
|
||||||
|
  基于 SPDY 协议优化,核心目标是提升性能:
|
||||||
|
- 解决 TCP 队头阻塞:UDP 无连接特性,单个流的阻塞不影响其他流。
|
||||||
|
- 更快的连接建立:QUIC 集成 TLS 1.3,减少握手次数(1-RTT 甚至 0-RTT 建立连接)。
|
||||||
|
- 更好的移动网络支持:支持连接迁移(如手机切换 WiFi/4G 时,连接不中断)。
|
||||||
|
|
||||||
|
## 组成
|
||||||
|
### 请求消息(Request)
|
||||||
|
  客户端向服务器发送的请求格式,由 请求行、请求头、空行、请求体 四部分组成:
|
||||||
|
```http
|
||||||
|
GET /api/courses/1 HTTP/1.1 # 请求行
|
||||||
|
Host: lms.example.com # 请求头(键值对形式)
|
||||||
|
Authorization: Bearer <token>
|
||||||
|
Accept: application/json
|
||||||
|
User-Agent: Mozilla/5.0 (Chrome/120.0.0.0)
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{"username": "admin", "password": "123456"} # 请求体(可选,POST/PUT 等方法常用)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 请求行
|
||||||
|
- 请求方法:表示请求的操作类型(常用方法如下表)。
|
||||||
|
- 请求 URI:指定服务器上的资源路径。
|
||||||
|
- 协议版本:如 HTTP/1.1、HTTP/2。
|
||||||
|
|
||||||
|
#### 请求头
|
||||||
|
  描述请求的附加信息,常用字段:
|
||||||
|
- Host:目标服务器域名(如 lms.example.com),HTTP/1.1 必选字段。
|
||||||
|
- User-Agent:客户端身份标识(如浏览器版本、App 名称)。
|
||||||
|
- Accept:客户端可接收的响应数据格式(如 application/json、text/html)。
|
||||||
|
- Content-Type:请求体的数据格式(如 application/json、multipart/form-data(文件上传))。
|
||||||
|
- Authorization:身份认证信息(如 Token、Basic Auth)。
|
||||||
|
- Cookie:客户端存储的会话信息(如登录态 Cookie)。
|
||||||
|
- Cache-Control:缓存控制策略(如 no-cache 表示不使用缓存)。
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
  可选部分,仅在需要向服务器提交数据时使用(如 POST 提交表单、PUT 更新资源),数据格式由 Content-Type 指定:
|
||||||
|
- 表单数据:application/x-www-form-urlencoded(如 username=admin&password=123)。
|
||||||
|
- JSON 数据:application/json(如 {"key": "value"})。
|
||||||
|
- 文件上传:multipart/form-data(如 LMS 系统的作业文件上传)。
|
||||||
|
- 纯文本:text/plain。
|
||||||
|
|
||||||
|
### 响应消息(Response)
|
||||||
|
  服务器向客户端返回的响应格式,由 状态行、响应头、空行、响应体 四部分组成:
|
||||||
|
```http
|
||||||
|
HTTP/1.1 200 OK # 状态行
|
||||||
|
Server: Nginx
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 128
|
||||||
|
Set-Cookie: sessionId=abc123; Path=/
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 状态行
|
||||||
|
- 协议版本:如 HTTP/1.1。
|
||||||
|
- 状态码:表示请求处理结果。
|
||||||
|
- 状态短语:状态码的文字描述(如 OK、Not Found)。
|
||||||
|
|
||||||
|
#### HTTP状态码
|
||||||
|
| 分类 | 状态码范围 | 含义 | 常用码 |
|
||||||
|
|------|------------|-----------------------|-------------------------|
|
||||||
|
| 1xx | 100-199 | 信息性响应(临时响应)| 100 Continue(预检通过)|
|
||||||
|
| 2xx | 200-299 | 成功响应 | 200 OK(成功)、201 Created(资源创建成功)、204 No Content(成功无响应体)|
|
||||||
|
| 3xx | 300-399 | 重定向 | 301 永久重定向、302 临时重定向、304 Not Modified(缓存有效)|
|
||||||
|
| 4xx | 400-499 | 客户端错误 | 400 Bad Request(请求参数错误)、401 Unauthorized(未认证)、403 Forbidden(权限不足)、404 Not Found(资源不存在)、405 Method Not Allowed(请求方法不支持)|
|
||||||
|
| 5xx | 500-599 | 服务器错误 | 500 Internal Server Error(服务器内部错误)、502 Bad Gateway(网关错误)、503 Service Unavailable(服务不可用)、504 Gateway Timeout(网关超时)|
|
||||||
|
|
||||||
|
#### 响应头
|
||||||
|
  描述响应的附加信息,常用字段:
|
||||||
|
- Server:服务器软件标识(如 Nginx、Tomcat)。
|
||||||
|
- Content-Type:响应体的数据格式(如 application/json、text/html)。
|
||||||
|
- Content-Length:响应体的字节大小。
|
||||||
|
- Set-Cookie:服务器向客户端设置 Cookie(如登录态、会话 ID)。
|
||||||
|
- Cache-Control:缓存控制策略(如 max-age=3600 表示缓存 1 小时)。
|
||||||
|
- Access-Control-Allow-Origin:跨域资源共享(CORS)配置(如 * 表示允许所有域名跨域)。
|
||||||
|
- Location:重定向目标地址(3xx 状态码必选)。
|
||||||
|
|
||||||
|
#### 响应体
|
||||||
|
  服务器返回的核心数据,数据格式由 Content-Type 指定,常见格式:
|
||||||
|
- JSON:前后端分离项目首选(如 {"code": 200, "data": [...]})。
|
||||||
|
- HTML:传统 Web 页面(如静态网页、JSP 页面)。
|
||||||
|
- 图片 / 视频:二进制流(如 image/jpeg、video/mp4)。
|
||||||
|
- 纯文本:text/plain。
|
||||||
|
|
||||||
|
# WebSocket
|
||||||
|
## 定义
|
||||||
|
  WebSocket 是一种全双工、双向、持久化的网络通信协议(属于应用层协议),由 HTML5 规范定义,专门解决 HTTP 协议无法实现服务器主动向客户端推送数据的问题。
|
||||||
|
  它的核心特点是:一旦客户端与服务器建立连接,双方就可以在这个连接上实时、双向地发送数据,无需像 HTTP 那样每次通信都由客户端发起请求,非常适合实时通信场景(如聊天、直播弹幕、实时数据监控、在线协作等)。
|
||||||
|
|
||||||
|
| 特性 | HTTP | WebSocket |
|
||||||
|
|---------------------|-------------------------------|-------------------------------|
|
||||||
|
| 通信方向 | 单向(客户端请求→服务器响应)| 全双工(双方可同时发数据)|
|
||||||
|
| 连接类型 | 短连接 / 长连接(需重复请求) | 持久连接(一次建立,持续通信) |
|
||||||
|
| 数据传输效率 | 每次请求带大量头部信息,效率低 | 连接建立后仅传输数据,开销小 |
|
||||||
|
| 服务器主动推送 | 不支持(HTTP/2 的 Server Push 仅能推送资源,非实时数据) | 原生支持,可主动向客户端发数据 |
|
||||||
|
| 协议标识 | http:// / https:// | ws:// / wss://(加密版)|
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
### 握手过程
|
||||||
|
1. 客户端发送 HTTP 请求,请求头包含 Upgrade: websocket 和 Connection: Upgrade(表示要升级为 WebSocket 协议);
|
||||||
|
2. 服务器响应 101 Switching Protocols,握手成功,连接转为 WebSocket 持久连接;
|
||||||
|
3. 后续通信不再使用 HTTP 格式,而是 WebSocket 帧格式(二进制 / 文本)。
|
||||||
|
|
||||||
|
  请求头:
|
||||||
|
```http
|
||||||
|
GET /chat HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Upgrade: websocket # 核心:请求升级为WebSocket协议
|
||||||
|
Connection: Upgrade # 核心:表示连接要升级
|
||||||
|
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== # 客户端生成的随机密钥,用于验证
|
||||||
|
Sec-WebSocket-Version: 13 # 指定WebSocket版本(主流为13)
|
||||||
|
Origin: https://example.com # 跨域验证
|
||||||
|
```
|
||||||
|
|
||||||
|
  响应头:
|
||||||
|
```http
|
||||||
|
HTTP/1.1 101 Switching Protocols
|
||||||
|
Upgrade: websocket
|
||||||
|
Connection: Upgrade
|
||||||
|
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= # 服务器加密后的密钥,客户端验证
|
||||||
|
```
|
||||||
|
|
||||||
|
### 全双工通信
|
||||||
|
  此时 HTTP 连接已升级为 WebSocket 连接,双方可以通过这个连接实时、双向地发送数据。数据传输采用帧(Frame) 格式,支持文本数据和二进制数据(如图片、视频流)。
|
||||||
|
|
||||||
|
### 帧格式
|
||||||
|
  WebSocket 数据以帧为单位传输,帧头包含操作码(文本帧 0x01、二进制帧 0x02、关闭帧 0x08 等)、掩码(客户端发送数据需掩码,服务器无需);
|
||||||
|
|
||||||
|
### 无同源限制
|
||||||
|
  WebSocket 不遵循同源策略(但服务器可通过 Origin 头限制跨域);
|
||||||
|
|
||||||
|
### 心跳机制
|
||||||
|
  通过 Ping/Pong 帧维持连接(避免网络设备断开空闲连接,如 LMS 系统需定期发送 Ping 帧,服务器回复 Pong 帧)。
|
||||||
|
|
||||||
|
# MQTT
|
||||||
|
## 定义
|
||||||
|
  MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一种轻量级、低带宽、低功耗的发布 / 订阅(Publish/Subscribe)模式物联网(IoT)通信协议,由 IBM 于 1999 年设计,核心目标是解决受限设备(如传感器、嵌入式设备)和低带宽、不稳定网络环境下的高效数据传输问题。
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
- 发布者(Publisher):发送消息的设备 / 服务;
|
||||||
|
- 订阅者(Subscriber):接收消息的设备 / 服务;
|
||||||
|
- broker(代理服务器):核心中间件,接收发布者的消息,根据「主题(Topic)」转发给订阅者(如 EMQ X、Mosquitto、RabbitMQ 支持 MQTT 插件);
|
||||||
|
- 主题(Topic):消息的分类标识。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
### QoS(服务质量)等级
|
||||||
|
- QoS 0(最多一次):消息发送一次,不保证送达;
|
||||||
|
- QoS 1(至少一次):消息至少送达一次,可能重复;
|
||||||
|
- QoS 2(恰好一次):消息仅送达一次,最可靠。
|
||||||
|
|
||||||
|
### 轻量级
|
||||||
|
  头部开销极小(固定头部仅 2 字节),消息体支持二进制 / 文本,适合低带宽场景
|
||||||
|
|
||||||
|
### 保留消息(Retained Message)
|
||||||
|
  broker 保存某个主题的最后一条消息,新订阅者订阅后立即收到该消息
|
||||||
|
|
||||||
|
### 遗嘱消息(Will Message)
|
||||||
|
  客户端异常断开时,broker 自动发送预设消息
|
||||||
|
|
||||||
|
### 清洁会话(Clean Session)
|
||||||
|
  客户端断开连接后,broker 是否保留订阅信息和未送达消息
|
||||||
|
|
||||||
|
## 组成
|
||||||
|
  MQTT 消息由 固定头部(Fixed Header)、可变头部(Variable Header)、负载(Payload) 三部分组成:
|
||||||
|
| 部分 | 作用 |
|
||||||
|
|--------------|----------------------------------------------------------------------|
|
||||||
|
| 固定头部 | 必选,2 字节起,包含消息类型(如发布、订阅)、QoS 等级、是否保留消息等标识。 |
|
||||||
|
| 可变头部 | 可选,仅部分消息类型(如发布、订阅)需要,包含主题名、消息 ID 等信息。 |
|
||||||
|
| 负载 | 可选,消息的实际内容(如 JSON 字符串、二进制数据),例如 {"temperature": 25}。 |
|
||||||
|
| 负载 | 可选,消息的实际内容(如 JSON 字符串、二进制数据),例如 {"temperature": 25}。 |
|
||||||
@@ -192,3 +192,111 @@ public interface UserMapper {
|
|||||||
```
|
```
|
||||||
|
|
||||||
  需要执行`mvn compile`后检查`target/generated-sources`文件夹下是否存在生成的转换代码。
|
  需要执行`mvn compile`后检查`target/generated-sources`文件夹下是否存在生成的转换代码。
|
||||||
|
|
||||||
|
# 三、Bean Validation
|
||||||
|
  Spring Boot的数据校验基于JSR-303/JSR-380规范(Bean Validation),通常使用Hibernate Validator作为实现。
|
||||||
|
|
||||||
|
## 3.1 添加依赖
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.2 常用检验注解
|
||||||
|
  Java Bean Validation 常用注解
|
||||||
|
|
||||||
|
| 注解 | 适用类型 | 说明 |
|
||||||
|
|------|----------|------|
|
||||||
|
| `@NotNull` | 任意类型 | 值不能为 null |
|
||||||
|
| `@NotBlank` | CharSequence | 字符串不能为 null,且必须包含至少一个非空白字符 |
|
||||||
|
| `@NotEmpty` | CharSequence, Collection, Map, Array | 字符串/集合/数组不能为 null 且不能为空(长度/大小大于 0) |
|
||||||
|
| `@Size(min=, max=)` | 字符串、集合、数组 | 限制长度或大小在 min 和 max 之间 |
|
||||||
|
| `@Min(value)` | 数值类型 | 数值必须大于或等于指定值 |
|
||||||
|
| `@Max(value)` | 数值类型 | 数值必须小于或等于指定值 |
|
||||||
|
| `@Email` | 字符串 | 字符串必须是合法的电子邮件地址格式 |
|
||||||
|
| `@Pattern(regexp=)` | 字符串 | 字符串必须匹配指定的正则表达式 |
|
||||||
|
| `@Future` / `@Past` | 日期时间类型 | 日期必须在当前时间的未来 / 过去 |
|
||||||
|
|
||||||
|
## 3.3 使用方法
|
||||||
|
```java
|
||||||
|
public class UserDTO {
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@Size(min = 3, max = 20, message = "用户名长度必须在3到20个字符之间")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
@Size(min = 8, message = "密码长度至少为8个字符")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
|
private String email;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
  在Controller的方法参数前使用@Valid或@Validated注解来触发校验:
|
||||||
|
```java
|
||||||
|
@RestController
|
||||||
|
public class UserController {
|
||||||
|
@PostMapping("/users")
|
||||||
|
public String createUser(@Valid @RequestBody UserDTO userDTO) {
|
||||||
|
return "用户创建成功";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.4 处理校验错误
|
||||||
|
```java
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
|
||||||
|
Map<String, String> errors = new HashMap<>();
|
||||||
|
ex.getBindingResult().getAllErrors().forEach((error) -> {
|
||||||
|
String fieldName = ((FieldError) error).getField();
|
||||||
|
String errorMessage = error.getDefaultMessage();
|
||||||
|
errors.put(fieldName, errorMessage);
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.5 自定义注解
|
||||||
|
```java
|
||||||
|
@Documented
|
||||||
|
@Constraint(validatedBy = PhoneValidator.class)
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface PhoneNumber {
|
||||||
|
String message() default "手机号码格式不正确";
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
  校验规则:
|
||||||
|
```java
|
||||||
|
public class PhoneValidator implements ConstraintValidator<PhoneNumber, String> {
|
||||||
|
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return true; // 使用@NotBlank等注解处理空值
|
||||||
|
}
|
||||||
|
return PHONE_PATTERN.matcher(value).matches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
  使用自定义校验:
|
||||||
|
```java
|
||||||
|
public class UserDTO {
|
||||||
|
@PhoneNumber
|
||||||
|
private String mobile;
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -17,6 +17,7 @@ SpringBoot 框架学习系列:
|
|||||||
- [SpringBoot Starter原理](/Web-Backend/SpringBoot/SpringBootStarter)
|
- [SpringBoot Starter原理](/Web-Backend/SpringBoot/SpringBootStarter)
|
||||||
- [SpringBoot Bean简介](/Web-Backend/SpringBoot/SpringBootBean)
|
- [SpringBoot Bean简介](/Web-Backend/SpringBoot/SpringBootBean)
|
||||||
- [SpringBoot3原生镜像](/Web-Backend/SpringBoot/SpringBoot3-GraalVM)
|
- [SpringBoot3原生镜像](/Web-Backend/SpringBoot/SpringBoot3-GraalVM)
|
||||||
|
- [SpingBoot技巧](/Web-Backend/SpringBoot/SpingBoot-Skills)
|
||||||
|
|
||||||
### 🐍 FastAPI
|
### 🐍 FastAPI
|
||||||
Python FastAPI 框架学习:
|
Python FastAPI 框架学习:
|
||||||
@@ -30,4 +31,4 @@ Python FastAPI 框架学习:
|
|||||||
- [Flyway简单使用](/Web-Backend/Others/Flyway)
|
- [Flyway简单使用](/Web-Backend/Others/Flyway)
|
||||||
- [MyBatis简介和使用](/Web-Backend/Others/MyBatis)
|
- [MyBatis简介和使用](/Web-Backend/Others/MyBatis)
|
||||||
- [RustFS简介和使用](/Web-Backend/Others/RustFS)
|
- [RustFS简介和使用](/Web-Backend/Others/RustFS)
|
||||||
- [JsonView和MapStruct使用](/Web-Backend/Others/JsonView-MapStruct)
|
- [网络编程简介](/Web-Backend/Others/Netword-Program)
|
||||||
Reference in New Issue
Block a user