- 发布日期
HTTP协议
- 作者
- 姓名
- 缘
- 社交账号
文章目录
HTTP协议
HTTP 全称为 Hyper Text Transfer Protocol,即超文本传输协议。
它规定了浏览器和服务器之间进行数据传输时需要遵守的规则。
浏览器 服务器
─────── HTTP 请求 ────────>
<────── HTTP 响应 ─────────
浏览器发送给服务器的数据称为请求数据,服务器返回给浏览器的数据称为响应数据。
HTTP协议的特点
1. 基于 TCP 协议
HTTP 基于 TCP 协议进行数据传输。TCP 是面向连接的协议,浏览器和服务器建立连接后再传输数据。
2. 基于请求—响应模型
一次请求对应一次响应,并且请求必须由客户端主动发起。
浏览器发送请求
↓
服务器接收并处理请求
↓
服务器返回响应
3. HTTP 是无状态协议
HTTP 对之前发生过的请求没有记忆能力,每一次请求和响应都是独立的。
例如,浏览器第一次请求服务器完成登录,第二次再请求个人信息时,仅靠 HTTP 协议本身,服务器并不知道这两个请求来自同一个已经登录的用户。
无状态的特点:
- 优点:每次请求都可以独立处理,速度快。
- 缺点:多次请求之间不能直接共享数据。
HTTP请求协议
HTTP 请求是浏览器发送给服务器的数据。
一份完整的 HTTP 请求由三部分组成:
- 请求行
- 请求头
- 请求体
例如:
POST /user/login HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
username=Tom&password=123
其中:
POST /user/login HTTP/1.1 请求行
Host: localhost:8080 请求头
User-Agent: Mozilla/5.0 请求头
Content-Type: ... 请求头
Content-Length: 27 请求头
username=Tom&password=123 请求体
请求头和请求体之间存在一个空行,用来表示请求头已经结束。
请求行
请求行位于请求数据的第一行,格式为:
请求方式 资源路径 协议版本
例如:
GET /hello?name=Tom HTTP/1.1
这三个部分分别表示:
| 内容 | 说明 |
|---|---|
GET | 本次请求使用的请求方式 |
/hello?name=Tom | 请求的资源路径以及查询参数 |
HTTP/1.1 | 使用的 HTTP 协议版本 |
请求头
请求头从请求数据的第二行开始,每一行都是一组键值对:
key: value
常见请求头如下:
| 请求头 | 说明 |
|---|---|
Host | 请求的主机名和端口 |
User-Agent | 浏览器和操作系统等客户端信息 |
Accept | 浏览器能够接收的资源类型 |
Accept-Language | 浏览器偏好的语言 |
Accept-Encoding | 浏览器支持的压缩类型,例如 gzip、deflate |
Content-Type | 请求体中数据的类型 |
Content-Length | 请求体的大小,单位为字节 |
例如:
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/json
Accept-Language: zh-CN,zh
Accept-Encoding: gzip, deflate
请求体
请求体用于存放提交给服务器的数据。
它与请求头之间隔着一个空行,主要出现在带有请求数据的请求中,例如 POST 请求。
POST /user/login HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=Tom&password=123
最后一行就是请求体:
username=Tom&password=123
GET与POST请求
GET请求
GET 请求通常将请求参数放在请求行的资源路径后面:
GET /brand/findAll?name=OPPO&status=1 HTTP/1.1
其中:
?name=OPPO&status=1
是查询字符串。
GET 请求的特点:
- 请求参数位于 URL 中。
- 通常没有请求体。
- 浏览器会对 URL 长度进行限制,因此能够携带的数据量有限。
POST请求
POST 请求通常将请求参数放在请求体中:
POST /brand HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
name=OPPO&status=1
POST 请求的特点:
- 请求参数位于请求体中。
- 参数不会直接显示在浏览器地址栏中。
- 不受浏览器 URL 长度的限制,更适合提交较多数据。
请求数据的完整结构
GET /request?name=Tomcat&age=10 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: zh-CN
这是一份 GET 请求:
- 请求行:
GET /request?name=Tomcat&age=10 HTTP/1.1 - 请求头:从
Host开始的所有键值对 - 请求体:没有请求体
POST 请求示例:
POST /request HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
name=Tomcat&age=10
这份请求包含请求行、请求头和请求体三个部分。
获取HTTP请求数据
HTTP 请求数据不需要程序员自己按照字符串逐行解析。
Web 服务器 Tomcat 接收到请求后,会按照 HTTP 协议解析请求数据,并将解析结果封装到 HttpServletRequest 对象中。
HTTP 请求数据
↓
Tomcat 解析请求
↓
HttpServletRequest
↓
Controller 方法读取请求信息
Controller 可以直接通过 HttpServletRequest 获取请求数据。
@RequestMapping("/request")
public String request(HttpServletRequest request) {
// 获取请求参数
String name = request.getParameter("name");
// 获取请求路径
String uri = request.getRequestURI();
// 获取完整请求地址
String url = request.getRequestURL().toString();
// 获取请求头
String userAgent = request.getHeader("User-Agent");
// 获取请求方式
String method = request.getMethod();
// 获取查询字符串
String queryString = request.getQueryString();
return "request success";
}
假设浏览器访问:
http://localhost:8080/request?name=Tomcat&age=10
各方法可能得到:
| 方法 | 结果 |
|---|---|
getParameter("name") | Tomcat |
getRequestURI() | /request |
getRequestURL() | http://localhost:8080/request |
getHeader("User-Agent") | 浏览器的 User-Agent 信息 |
getMethod() | GET |
getQueryString() | name=Tomcat&age=10 |
因此,在 Java Web 开发中可以先记住:
Tomcat 负责解析 HTTP 请求,
HttpServletRequest负责封装解析后的请求信息。
HTTP响应协议
HTTP 响应是服务器处理完请求后,返回给浏览器的数据。
一份完整的 HTTP 响应由三部分组成:
- 响应行
- 响应头
- 响应体
例如:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 24
{"name":"Tom","age":18}
其中:
HTTP/1.1 200 OK 响应行
Content-Type: application/json 响应头
Content-Length: 24 响应头
{"name":"Tom","age":18} 响应体
响应行
响应行是响应数据的第一行,格式为:
协议版本 状态码 状态描述
例如:
HTTP/1.1 200 OK
表示服务器使用 HTTP/1.1 协议返回响应,本次请求处理成功。
HTTP状态码
状态码用于表示服务器处理请求的结果。
| 分类 | 说明 |
|---|---|
1xx | 响应中,表示请求已经接收,客户端可以继续后续操作 |
2xx | 成功,表示请求已经成功接收并处理完成 |
3xx | 重定向,需要客户端再次发起请求 |
4xx | 客户端错误,例如请求不存在的资源或没有访问权限 |
5xx | 服务器错误,例如服务端程序运行时抛出异常 |
常见状态码:
| 状态码 | 说明 |
|---|---|
200 OK | 请求成功 |
404 Not Found | 请求的资源不存在 |
500 Internal Server Error | 服务器程序发生错误 |
重定向
重定向表示服务器没有直接返回最终资源,而是告诉浏览器到另一个地址重新发送请求。
浏览器请求资源 A
↓
服务器返回 3xx,并在 Location 中指定资源 B
↓
浏览器再次请求资源 B
↓
服务器返回资源 B
响应示例:
HTTP/1.1 302 Found
Location: /login
浏览器收到响应后,会再次向 /login 发起请求。
响应头
响应头从响应数据的第二行开始,同样使用键值对格式:
key: value
常见响应头如下:
| 响应头 | 说明 |
|---|---|
Content-Type | 响应体中数据的类型,例如 text/html、application/json |
Content-Length | 响应体的长度,单位为字节 |
Content-Encoding | 响应数据使用的压缩算法,例如 gzip |
Cache-Control | 告诉浏览器如何缓存响应数据 |
Set-Cookie | 告诉浏览器设置 Cookie |
Location | 重定向时指定新的请求地址 |
例如:
Content-Type: application/json
Content-Encoding: gzip
Cache-Control: max-age=300
响应体
响应体用于存放服务器真正返回的数据。
返回 HTML:
<h1>Hello Response</h1>
返回 JSON:
{
"id": 1,
"username": "Tom"
}
浏览器最终展示或处理的主要内容,就位于响应体中。
设置HTTP响应数据
Tomcat 会将 HTTP 响应相关操作封装到 HttpServletResponse 对象中。
程序可以通过它设置响应状态码、响应头和响应体。
使用HttpServletResponse
@RequestMapping("/response")
public void response(HttpServletResponse response) throws IOException {
// 设置响应状态码
response.setStatus(401);
// 设置响应头
response.setHeader("itheima", "itheima");
// 设置响应体
response.getWriter().write("<h1>Hello Response</h1>");
}
对应关系:
| Java代码 | HTTP响应部分 |
|---|---|
response.setStatus(401) | 响应行中的状态码 |
response.setHeader(...) | 响应头 |
response.getWriter().write(...) | 响应体 |
使用ResponseEntity
Spring 还可以使用 ResponseEntity 封装完整响应:
@RequestMapping("/response")
public ResponseEntity<String> response() {
return ResponseEntity
.status(401)
.header("group", "itcast")
.body("<h1>Hello Response</h1>");
}
其中:
status(...) 设置响应状态码
header(...) 设置响应头
body(...) 设置响应体
通常情况下,程序员不需要手动设置所有响应信息。
Controller 返回普通字符串、对象或集合时,Spring Boot 和 Tomcat 会根据请求处理结果自动生成合适的响应状态码、响应头和响应体。只有存在特殊响应要求时,才需要直接使用 HttpServletResponse 或 ResponseEntity。
请求与响应的整体过程
1. 浏览器按照 HTTP 格式生成请求数据
2. 浏览器将请求发送给服务器
3. Tomcat 解析请求并封装为 HttpServletRequest
4. Controller 获取请求信息并处理业务
5. 程序生成响应数据
6. Tomcat 按照 HTTP 格式将响应发送给浏览器
7. 浏览器解析响应并展示结果
核心关系:
HTTP请求 → HttpServletRequest
HTTP响应 → HttpServletResponse
HTTP 协议规定数据传输格式,Tomcat 负责解析和封装,程序员通过 Java 对象获取请求数据、设置响应数据。