
在使用 Rest Assured 进行 API 测试时,我们经常会遇到 HTTP 重定向。Rest Assured 对不同类型的请求和重定向状态码有着不同的默认行为:
用户尝试使用 given().config(RestAssured.config().redirect(redirectConfig().followRedirects(true))) 等配置来启用重定向,但这些配置通常对 GET/HEAD 请求的 30x 重定向更为有效,或者它们控制的是 302/303 重定向到 GET 请求的行为。对于 POST 请求的 307 临时重定向,即使设置 followRedirects(true),也可能不会按预期工作,因为 Rest Assured 内部逻辑对此有更严格的限制。maxRedirects(0) 则会直接禁用所有重定向,这与期望自动跟随重定向的初衷相悖。
鉴于 Rest Assured 不会自动处理 POST 请求的 307 临时重定向,我们需要采用手动方式来模拟这一过程。核心思路是:发送第一个 POST 请求并禁用自动重定向,然后检查响应状态码和 Location 头,最后手动构建并发送第二个 POST 请求到重定向目标。
以下是一个通用的处理函数示例:
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.builder.RequestSpecBuilder;
import static io.restassured.RestAssured.given;
import static io.restassured.config.RedirectConfig.redirectConfig;
public class RedirectHandler {
/**
* 处理 POST 请求的 307 临时重定向。
* 如果收到 307 状态码,则手动跟随重定向。
*
* @param initialUrl 初始请求的 URL。
* @param requestBody 初始请求的请求体。
* @param contentType 初始请求的 Content-Type。
* @param initialRequestSpec 初始请求的 RequestSpecification(可选,用于传递额外的头、认证等)。
* @return 最终的响应对象。
*/
public static Response handlePostRedirect(String initialUrl, Object requestBody, ContentType contentType, RequestSpecification initialRequestSpec) {
// 构建初始请求,禁用自动重定向
RequestSpecification request = given()
.config(RestAssured.config().redirect(redirectConfig().followRedirects(false))) // 明确禁用自动重定向
.contentType(contentType)
.body(requestBody)
.log().all(); // 打印所有请求信息,便于调试
// 如果提供了额外的请求规范,合并它们
if (initialRequestSpec != null) {
request.spec(initialRequestSpec);
}
// 步骤 1: 发送原始 POST 请求
Response initialResponse = request.when().post(initialUrl);
// 步骤 2: 检查状态码是否为 307
if (initialResponse.statusCode() == 307) {
String redirectLocation = initialResponse.getHeader("Location");
if (redirectLocation == null || redirectLocation.isEmpty()) {
System.err.println("收到 307 临时重定向,但 Location 头缺失或为空。无法处理重定向。");
return initialResponse; // 无法处理,返回原始响应
}
System.out.println("收到 307 临时重定向。正在重定向到: " + redirectLocation);
// 步骤 3 & 4: 提取 Location 头,并使用相同的请求方法和请求体发送第二个请求
// 注意:第二个请求需要继承第一个请求的 Cookies 和其他必要的头信息
RequestSpecification followUpRequest = given()
.config(RestAssured.config().redirect(redirectConfig().followRedirects(true))) // 第二个请求可以启用自动重定向,或者继续禁用手动处理
.contentType(contentType)
.body(requestBody) // 重新发送相同的请求体
.cookies(initialResponse.getDetailedCookies()) // 传递会话 Cookies
.log().all(); // 打印所有请求信息,便于调试
// 如果原始请求有认证或其他头信息,需要手动添加到 followUpRequest
// 例如:initialRequestSpec 中的 Authorization 头
// 更好的做法是在 initialRequestSpec 中包含所有通用头,并复用
if (initialRequestSpec != null) {
// 这里需要小心,如果 initialRequestSpec 包含了 baseURI 等信息,可能需要调整
// 简单起见,我们只复制 header。更健壮的方案是逐个复制或使用 merge()
initialRequestSpec.getHeaders().forEach(header -> {
if (!header.getName().equalsIgnoreCase("Content-Type")) { // Content-Type 已经设置
followUpRequest.header(header.getName(), header.getValue());
}
});
}
return followUpRequest.when().post(redirectLocation); // 向重定向地址发送 POST 请求
} else {
System.out.println("未收到 307 临时重定向,返回初始响应。状态码: " + initialResponse.statusCode());
return initialResponse;
}
}
public static void main(String[] args) {
// 设置 Rest Assured 的基本 URI
RestAssured.baseURI = "http://localhost:8080"; // 替换为你的实际 baseURL
// 示例:模拟一个初始 POST 请求,它会返回 307 重定向
String initialEndpoint = "/api/login"; // 假设这是初始认证端点
String username = "testUser";
String password = "testPassword";
String requestBody = "{\n" +
" \"username\": \"" + username + "\",\n" +
"\"password\": \"" + password + "\" \n" +
"}";
// 可以在这里构建一个 RequestSpecBuilder 来包含通用头或认证信息
RequestSpecification commonSpec = new RequestSpecBuilder()
.addHeader("X-Custom-Header", "Value")
.build();
Response finalResponse = handlePostRedirect(initialEndpoint, requestBody, ContentType.JSON, commonSpec);
System.out.println("\n--- 最终响应 ---");
System.out.println("最终响应状态码: " + finalResponse.statusCode());
System.out.println("最终响应体: " + finalResponse.asString());
// 如果认证成功,可以从 finalResponse 中提取 AccessToken
// String accessToken = JsonPath.from(finalResponse.asString()).get("AccessToken");
// System.out.println("AccessToken: " + accessToken);
}
}代码解释与注意事项:
if (initialResponse.statusCode() == 307) {
// ... 发送 POST 请求到 Location ...
} else if (initialResponse.statusCode() == 302 || initialResponse.statusCode() == 303) {
// ... 发送 GET 请求到 Location ...
}通过上述手动处理策略,您将能够有效地解决 Rest Assured 在处理 POST 请求时遇到的 307 临时重定向问题,确保您的 API 测试能够准确地模拟客户端行为。
以上就是Rest Assured 中处理 POST 请求的 307 临时重定向的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号