web-第五次课后作业

本次作业以一个基础的Spring Boot项目,来初步了解HTTP 请求与响应以及在Apifox上面的操作。

HTTP 请求与响应 ------ 浏览器与服务器的通信(Apifox相关操作)

一、浏览器与服务器的通信模型

复制代码
┌──────────┐     HTTP 请求(Request)     ┌──────────────┐
│  浏览器   │ ─────────────────────────> │   服务器       │
│ (客户端)  │                            │ (Spring Boot) │
│          │ <───────────────────────── │              │
└──────────┘     HTTP 响应(Response)    └──────────────┘

整个过程是请求-响应模式(Request-Response),每次交互都由客户端(浏览器/Apifox)主动发起,服务器被动响应。

当你在浏览器输入 http://localhost:8080/register 时:

  1. 浏览器解析URL,提取出协议 (http)、主机 (localhost)、端口 (8080)、路径(/register)
  2. 浏览器向 localhost:8080 建立一个 TCP 连接
  3. 浏览器发送一个 HTTP 请求报文给服务器
  4. Spring Boot 接收到请求,路由到对应的方法
  5. 服务器返回一个 HTTP 响应报文(包含 HTML 页面或其他数据)
  6. 浏览器解析响应,渲染页面

二、HTTP 请求协议

一个 HTTP 请求报文由四部分组成:

复制代码
请求行
请求头
空行(标记头部结束)
请求体(可选,GET 请求通常没有)

2.1 请求行

复制代码
GET /hello?name=llz HTTP/1.1
└┬┘ └────────────────┘ └──┬──┘
 │           │             └── HTTP 版本
 │           └── 请求URI(路径 + 查询参数 Query String)
 └── 请求方法(GET / POST / PUT / DELETE ...)

2.2 请求头

请求头携带附加信息,常见的请求头:

请求头 含义
User-Agent 客户端身份标识(浏览器类型、版本)
Accept 客户端能接收的数据类型
Accept-Encoding 客户端支持的压缩格式
Content-Type 请求体的数据格式(POST 时重要)
Content-Length 请求体的字节数

2.3 实际请求示例

http 复制代码
GET /hello?name=llz HTTP/1.1
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2026.1.3
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*

三、GET 与 POST 的区别

维度 GET POST
数据位置 URL 的 ? 后面(Query String) 请求体(Body)里面
可见性 参数暴露在地址栏,可被收藏/分享 参数不显示在地址栏
长度限制 URL 长度有限制(约2KB) 理论上无限制
语义 "获取"资源,不改变服务器数据 "提交"数据,通常会改变服务器状态
缓存 可被浏览器缓存 不会被缓存
Apifox 操作 参数填在 Params / Query 区域 参数填在 Body 区域

GET 请求示例

浏览器地址栏输入 http://localhost:8080/hello?name=zhangsan,实际上就是发起了一个 GET 请求,参数 name=zhangsan 通过 URL 传递。

POST 请求示例

表单提交是典型的 POST 场景:

html 复制代码
<form action="/register" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <button type="submit">注册</button>
</form>

点击"注册"后,浏览器会将表单数据放入请求体发送:

http 复制代码
POST /register HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 47

username=zhangsan&password=123456&phone=13800138000

注意 :如果用 GET 方式传参数拼在 URL 后面(如 POST /register?username=xxx),虽然也能被服务器解析,但这不是标准用法,POST 的参数应该放在请求体中。


四、HTTP 响应协议

一个 HTTP 响应报文同样由四部分组成:

复制代码
状态行
响应头
空行
响应体

4.1 状态行

复制代码
HTTP/1.1 200 OK
└──┬──┘ └┬─┘ └┬┘
   │     │    └── 状态描述
   │     └── 状态码
   └── HTTP 版本

4.2 常见状态码

状态码 含义 说明
200 OK 请求成功
301 Moved Permanently 永久重定向
302 Found 临时重定向
400 Bad Request 客户端请求有误
404 Not Found 资源未找到
500 Internal Server Error 服务器内部错误

4.3 响应头

常见的响应头:

响应头 含义
Content-Type 响应体的数据类型(text/htmlapplication/json 等)
Content-Length 响应体的字节数
Set-Cookie 要求浏览器保存 Cookie

4.4 实际响应示例

http 复制代码
HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Content-Length: 15

Hello,zhangsan!

五、项目代码解析

5.1 项目结构

复制代码
src/main/java/com/example/demo/
├── DemoApplication.java      # Spring Boot 启动入口
├── HelloController.java      # 演示 GET 请求,返回纯文本
└── RegController.java        # 演示 GET + POST 请求,处理注册表单

src/main/resources/
├── application.yml            # 配置文件(端口号等)
└── templates/
    ├── register.html          # 注册表单页面
    └── register-success.html  # 注册成功页面

5.2 HelloController ------ 纯 GET,返回字符串

java 复制代码
@RestController                    // = @Controller + @ResponseBody,返回数据而非页面
public class HelloController {
    @GetMapping("/hello")          // 只处理 GET 请求
    public String hello(String name) {
        return "Hello," + name + "!";
    }
}
  • @RestController:表示返回的是数据(字符串/JSON),不是 HTML 页面
  • @GetMapping("/hello"):只匹配 GET /hello 请求
  • 参数 String name:Spring 自动从 URL 的 ?name=xxx 中取值绑定

测试

  • GET /hello?name=llz → 响应 Hello,llz!
  • GET /hello → 响应 Hello,null!(没传参数,name 为 null)

5.3 RegController ------ 同时处理 GET 和 POST

java 复制代码
@Controller                       // 返回模板页面(HTML)
public class RegController {

    @GetMapping("/register")      // 浏览器访问页面 → GET 请求
    public String registerPage() {
        return "register";        // Thymeleaf 渲染 templates/register.html
    }

    @PostMapping("/register")     // 表单提交 → POST 请求
    public String register(
            @RequestParam String username,
            @RequestParam String password,
            @RequestParam String phone,
            Model model) {
        model.addAttribute("username", username);
        model.addAttribute("phone", phone);
        return "register-success"; // Thymeleaf 渲染 templates/register-success.html
    }
}

核心设计 :同一个路径 /register,根据 HTTP 方法不同,执行不同逻辑:

请求 触发方法 行为
GET /register registerPage() 返回注册表单页面给用户填写
POST /register register() 接收表单数据,返回注册成功页面

这是 RESTful 风格的核心思想:同一 URL,不同方法,不同操作


六、完整数据流(以注册为例)

复制代码
步骤1: 用户在浏览器输入 http://localhost:8080/register
      │
      ├── 浏览器发起: GET /register(无参数)
      ├── RegController.registerPage() 被调用
      ├── 返回 register.html 的渲染结果
      └── 浏览器展示注册表单

步骤2: 用户填写表单并点击"注册"按钮
      │
      ├── 浏览器发起: POST /register(参数在请求体中)
      ├── RegController.register() 被调用
      ├── @RequestParam 提取 username/password/phone
      ├── 把数据放入 Model
      ├── 返回 register-success.html 的渲染结果
      └── 浏览器展示"注册成功",显示用户名和手机号

七、Apifox 操作指南

7.1 GET 请求测试

以测试 /hello 接口为例:

  1. 新建请求,方法选 GET

  2. URL 填 http://localhost:8080/hello

  3. Query 参数 区域添加:

    参数名 参数值
    name llz
  4. 点击 发送

  5. 查看响应体,应返回 Hello,llz!

7.2 POST 请求测试

以测试 /register 接口为例:

第一步:获取注册页面(GET)

  • 方法选 GET,URL 填 http://localhost:8080/register,发送
  • 返回注册表单的 HTML 页面

第二步:提交注册数据(POST)

  • 方法选 POST ,URL 填 http://localhost:8080/register

  • Body 区域选择数据类型为 x-www-form-urlencoded

  • 添加参数:

    参数名 参数值
    username llz
    password 123456
    phone 12345678912
  • 点击 发送

  • 返回注册成功页面,显示用户名和手机号

7.3 关键提醒

  • GET 请求:参数放在 Params / Query 区域 → 拼接在 URL 后面
  • POST 请求:参数放在 Body 区域 → 放在请求体里面
  • 不要把 POST 的参数拼在 URL 后面,这不是标准用法

八、总结

概念 说明
浏览器-服务器通信 请求-响应模式,客户端主动发起,服务器被动响应
HTTP 请求报文 请求行 + 请求头 + 空行 + 请求体
HTTP 响应报文 状态行 + 响应头 + 空行 + 响应体
GET 请求 获取资源,参数在 URL 后面(Query String)
POST 请求 提交数据,参数在请求体中(Body)
@GetMapping 只处理 GET 请求
@PostMapping 只处理 POST 请求
@RequestParam 提取请求参数(GET 的 Query String 或 POST 的 Body)
@RestController 返回数据(字符串/JSON)
@Controller 返回页面(配合 Thymeleaf 模板)
Apifox GET 操作 参数填在 Params 区域
Apifox POST 操作 参数填在 Body 区域

相关推荐
卷无止境12 小时前
FastAPI 权限管理实战:从 ACL 到 RBAC 的那些门道
后端·python·fastapi
程序员黑豆20 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC20 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea20 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
风流 少年20 小时前
Spring AI 2.0:Memory
java·后端·spring
浮生望21 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少21 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波00721 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis1 天前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝1 天前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps