在日常开发中,我们经常需要测试 API 接口。虽然 Postman 等工具很强大,但频繁切换工具还是会影响开发效率。今天给大家介绍 IntelliJ IDEA 中一个强大但经常被忽视的功能 —— HTTP 请求文件(.http)。本文将从基础到进阶,全面介绍这个功能的使用方法。
一、快速入门
1.1 创建请求文件
在 IDEA 中创建 HTTP 请求文件非常简单:
1. 右键项目目录
2. 选择
New
>HTTP Request
3. 输入文件名(例如
api-tests.http
)
1.2 第一个请求
### 获取用户列表
GET http://localhost:8080/api/users
### 创建新用户
POST http://localhost:8080/api/users
Content-Type: application/json
{
"name": "张三",
"email": "zhangsan@example.com",
"age": 25
}
使用方法:
• 将光标放在请求上
• 按下
Ctrl + Enter
(Windows/Linux)或Cmd + Enter
(Mac)• 右侧窗口会显示响应结果
二、基础功能详解
2.1 HTTP 方法支持
### GET 请求
GET http://api.example.com/users/1
### POST 请求
POST http://api.example.com/users
Content-Type: application/json
{
"name": "李四",
"email": "lisi@example.com"
}
### PUT 请求
PUT http://api.example.com/users/1
Content-Type: application/json
{
"name": "李四(已更新)"
}
### DELETE 请求
DELETE http://api.example.com/users/1
2.2 请求头设置
### 带认证的请求
GET http://api.example.com/secure-endpoint
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/json
Content-Type: application/json
2.3 请求参数
### URL 参数
GET http://api.example.com/users?page=1&size=10&sort=name
### 路径参数
GET http://api.example.com/users/{userId}/orders/{orderId}
三、环境变量配置
3.1 创建环境配置文件
创建 http-client.env.json
:
{
"dev": {
"baseUrl": "http://localhost:8080",
"token": "dev-token-123",
"username": "dev-admin",
"password": "dev-password"
},
"prod": {
"baseUrl": "https://api.company.com",
"token": "prod-token-456",
"username": "prod-admin",
"password": "prod-password"
}
}
3.2 使用环境变量
### 使用环境变量的请求
GET {{baseUrl}}/api/users
Authorization: Bearer {{token}}
### 登录请求
POST {{baseUrl}}/api/login
Content-Type: application/json
{
"username": "{{username}}",
"password": "{{password}}"
}
3.3 私密信息配置
创建 http-client.private.env.json
(注意加入 .gitignore):
{
"dev": {
"apiKey": "dev-key-123",
"webhookSecret": "dev-webhook-secret"
},
"prod": {
"apiKey": "prod-key-456",
"webhookSecret": "prod-webhook-secret"
}
}
四、高级功能与技巧
4.1 请求脚本
### 带验证脚本的请求
POST {{baseUrl}}/api/users
Content-Type: application/json
{
"name": "测试用户",
"email": "test@example.com"
}
> {%
client.test("创建用户成功", function() {
client.assert(response.status === 201);
client.assert(response.body.id != null);
client.global.set("userId", response.body.id);
});
%}
4.2 文件上传
### 单文件上传
POST {{baseUrl}}/api/upload
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="test.pdf"
Content-Type: application/pdf
< ./data/test.pdf
--WebAppBoundary--
### 多文件上传
POST {{baseUrl}}/api/upload-multiple
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="files"; filename="file1.pdf"
Content-Type: application/pdf
< ./data/file1.pdf
--WebAppBoundary
Content-Disposition: form-data; name="files"; filename="file2.pdf"
Content-Type: application/pdf
< ./data/file2.pdf
--WebAppBoundary--
4.3 动态变量
### 使用动态变量
POST {{baseUrl}}/api/products
Content-Type: application/json
{
"name": "商品{{$random.integer(1, 1000)}}",
"price": {{$random.float(10, 1000)}},
"sku": "SKU{{$random.alphanumeric(8)}}",
"createTime": "{{$timestamp}}"
}
五、完整业务场景示例
5.1 用户注册登录流程
### 1. 注册
POST {{baseUrl}}/api/auth/register
Content-Type: application/json
{
"username": "{{$random.alphabetic(8)}}",
"email": "{{$random.email}}",
"password": "{{$random.alphanumeric(12)}}"
}
> {%
client.test("注册成功", function() {
client.assert(response.status === 201);
client.global.set("userId", response.body.id);
client.global.set("userEmail", response.body.email);
});
%}
### 2. 登录
POST {{baseUrl}}/api/auth/login
Content-Type: application/json
{
"email": "{{userEmail}}",
"password": "{{password}}"
}
> {%
client.test("登录成功", function() {
client.assert(response.status === 200);
client.global.set("authToken", response.body.token);
});
%}
5.2 电商下单流程
### 1. 检查商品库存
GET {{baseUrl}}/api/products/{{productId}}/stock
> {%
client.test("库存检查", function() {
client.assert(response.status === 200);
client.assert(response.body.available > 0);
});
%}
### 2. 加入购物车
POST {{baseUrl}}/api/cart/items
Content-Type: application/json
Authorization: Bearer {{authToken}}
{
"productId": "{{productId}}",
"quantity": 1
}
### 3. 查看购物车
GET {{baseUrl}}/api/cart
Authorization: Bearer {{authToken}}
### 4. 创建订单
POST {{baseUrl}}/api/orders
Content-Type: application/json
Authorization: Bearer {{authToken}}
{
"cartId": "{{cartId}}",
"addressId": "{{addressId}}",
"couponCode": "SUMMER2024"
}
> {%
client.test("订单创建成功", function() {
client.assert(response.status === 201);
client.global.set("orderId", response.body.orderId);
client.global.set("orderAmount", response.body.totalAmount);
});
%}
### 5. 支付订单
POST {{baseUrl}}/api/payments
Content-Type: application/json
Authorization: Bearer {{authToken}}
{
"orderId": "{{orderId}}",
"amount": {{orderAmount}},
"method": "WECHAT"
}
六、调试与测试
6.1 响应断言
### 复杂响应断言
GET {{baseUrl}}/api/products
> {%
client.test("产品列表检查", function() {
// 状态码检查
client.assert(response.status === 200);
// 响应格式检查
client.assert(Array.isArray(response.body));
// 数据完整性检查
response.body.forEach(function(product) {
client.assert(product.id != null, "产品ID不能为空");
client.assert(product.name != null, "产品名称不能为空");
client.assert(product.price > 0, "产品价格必须大于0");
});
// 性能检查
client.assert(response.responseTime < 1000, "响应时间超过1秒");
});
%}
6.2 调试日志
### 调试信息打印
GET {{baseUrl}}/api/debug-test
> {%
// 请求信息
client.log("=== 请求信息 ===");
client.log("URL: " + request.url);
client.log("Method: " + request.method);
client.log("Headers: " + JSON.stringify(request.headers));
// 响应信息
client.log("=== 响应信息 ===");
client.log("Status: " + response.status);
client.log("Headers: " + JSON.stringify(response.headers));
// 响应体
if (response.body) {
client.log("Body: " + JSON.stringify(response.body, null, 2));
}
// 性能信息
client.log("Response Time: " + response.responseTime + "ms");
%}
6.3 批量测试
### 批量请求测试
GET {{baseUrl}}/api/performance-test
> {%
const startTime = new Date().getTime();
// 发起多次请求
for (let i = 0; i < 10; i++) {
client.log(`发起第 ${i + 1} 次请求`);
const response = client.execute();
client.assert(response.status === 200);
}
const endTime = new Date().getTime();
const duration = endTime - startTime;
client.log(`总耗时: ${duration}ms`);
client.log(`平均响应时间: ${duration / 10}ms`);
%}
HTTP 请求文件组织最佳实践
一、基本组织方式
1.1 使用标签组织
### @name userManagement
### @tags user, auth
### 1. 用户注册
POST {{baseUrl}}/api/users/register
Content-Type: application/json
{
"username": "testuser",
"email": "test@example.com"
}
### 2. 用户登录
# @name login
POST {{baseUrl}}/api/users/login
Content-Type: application/json
{
"email": "test@example.com",
"password": "password123"
}
> {%
client.global.set("authToken", response.body.token)
%}
### 3. 获取用户信息
# @name getUserInfo
GET {{baseUrl}}/api/users/me
Authorization: Bearer {{authToken}}
1.2 按模块分文件
api-tests/
├── auth/
│ ├── login.http # 认证相关请求
│ └── register.http # 注册相关请求
├── users/
│ ├── profile.http # 用户档案相关请求
│ └── settings.http # 用户设置相关请求
├── products/
│ ├── catalog.http # 商品目录相关请求
│ └── inventory.http # 库存相关请求
├── orders/
│ ├── create.http # 订单创建相关请求
│ └── payment.http # 支付相关请求
├── http-client.env.json # 环境配置
└── http-client.private.env.json # 私密配置
二、实际示例
2.1 认证模块 (auth.http)
### @name authRequests
### @tags authentication
### 登录
# @name login
POST {{baseUrl}}/api/auth/login
Content-Type: application/json
{
"email": "{{email}}",
"password": "{{password}}"
}
> {%
client.global.set("authToken", response.body.token)
%}
### 刷新Token
# @name refreshToken
POST {{baseUrl}}/api/auth/refresh
Authorization: Bearer {{authToken}}
### 登出
# @name logout
POST {{baseUrl}}/api/auth/logout
Authorization: Bearer {{authToken}}
2.2 用户模块 (users.http)
### @name userRequests
### @tags users
### 获取用户列表
# @name getUserList
GET {{baseUrl}}/api/users
Authorization: Bearer {{authToken}}
### 创建用户
# @name createUser
POST {{baseUrl}}/api/users
Authorization: Bearer {{authToken}}
Content-Type: application/json
{
"name": "新用户",
"email": "new@example.com",
"role": "user"
}
### 更新用户信息
# @name updateUser
PUT {{baseUrl}}/api/users/{{userId}}
Authorization: Bearer {{authToken}}
Content-Type: application/json
{
"name": "更新的名字"
}
2.3 商品模块 (products.http)
### @name productRequests
### @tags products
### 获取商品列表
# @name getProducts
GET {{baseUrl}}/api/products
Authorization: Bearer {{authToken}}
### 创建商品
# @name createProduct
POST {{baseUrl}}/api/products
Authorization: Bearer {{authToken}}
Content-Type: application/json
{
"name": "新商品",
"price": 99.99,
"description": "商品描述"
}
### 更新商品
# @name updateProduct
PUT {{baseUrl}}/api/products/{{productId}}
Authorization: Bearer {{authToken}}
Content-Type: application/json
{
"price": 88.88
}
三、高级组织技巧
3.1 使用请求变量
### 设置测试数据
# @name setupTestData
POST {{baseUrl}}/api/test-data
Content-Type: application/json
{
"scenario": "user-flow"
}
> {%
client.global.set("testUserId", response.body.userId)
client.global.set("testOrderId", response.body.orderId)
%}
### 使用测试数据
GET {{baseUrl}}/api/users/{{testUserId}}/orders/{{testOrderId}}
3.2 测试场景组织
### @name e2eTestScenario
### @tags e2e, test
### 1. 创建测试用户
# @name createTestUser
POST {{baseUrl}}/api/users
Content-Type: application/json
{
"name": "测试用户",
"email": "test@example.com"
}
> {%
client.global.set("userId", response.body.id)
%}
### 2. 创建测试订单
# @name createTestOrder
POST {{baseUrl}}/api/orders
Content-Type: application/json
{
"userId": "{{userId}}",
"items": [
{
"productId": "123",
"quantity": 1
}
]
}
> {%
client.global.set("orderId", response.body.id)
%}
### 3. 清理测试数据
# @name cleanupTestData
DELETE {{baseUrl}}/api/test-data
Content-Type: application/json
{
"userId": "{{userId}}",
"orderId": "{{orderId}}"
}