请求正文与标头
发送 POST 数据并设置标头
请求正文与标头 是 CoddyKit 上的免费 Java Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
请求正文和请求头
GET 请求很少需要正文,但 POST、PUT 和 PATCH 需要。JDK HTTP 客户端使用 BodyPublisher 对象提供请求正文,并使用构建器方法设置请求头。
本课介绍如何发送数据,以及如何控制 Content-Type 等请求头。
BodyPublishers.ofString
最简单的发布器会发送字符串正文。将它传递给请求构建器上的 POST(...) 方法。
BodyPublishers.noBody() 可用于没有正文的请求。
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
public class Main {
public static void main(String[] args) {
String json = "{\"name\":\"Ada\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users"))
.POST(BodyPublishers.ofString(json))
.build();
System.out.println("Method: " + request.method());
}
}设置单个请求头
使用 header(name, value) 添加一个请求头。要发送 JSON,您几乎总是需要设置 Content-Type。
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
public class Main {
public static void main(String[] args) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString("{}"))
.build();
System.out.println("Has Content-Type: " +
request.headers().firstValue("Content-Type").isPresent());
}
}一次设置多个请求头
headers(name1, value1, name2, value2, ...) 可以在一次调用中设置多个请求头。参数数量必须为偶数,否则会抛出 IllegalArgumentException。
import java.net.URI;
import java.net.http.HttpRequest;
public class Main {
public static void main(String[] args) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.headers(
"Accept", "application/json",
"Accept-Language", "en-US")
.GET()
.build();
System.out.println(request.headers().map().keySet());
}
}授权请求头
持有者令牌通过 Authorization 请求头发送。请将其值构建为字符串;绝不要将原始令牌写入日志。
public class Main {
public static void main(String[] args) {
String token = "abc123";
String headerValue = "Bearer " + token;
System.out.println("Authorization: Bearer ***");
System.out.println("Length: " + headerValue.length());
}
}PUT 和 DELETE
构建器提供了专用方法:PUT(publisher)、DELETE(),以及用于其他方法(例如 PATCH)的通用方法 method(name, publisher)。
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
public class Main {
public static void main(String[] args) {
HttpRequest patch = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users/1"))
.method("PATCH", BodyPublishers.ofString("{\"active\":true}"))
.build();
System.out.println("Method: " + patch.method());
}
}表单编码的正文
对于 application/x-www-form-urlencoded 数据,您需要手动构建正文字符串,对每个值进行 URL 编码,然后将其作为字符串发布。
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
String body = "name=" + URLEncoder.encode("Ada Lovelace", StandardCharsets.UTF_8)
+ "&role=" + URLEncoder.encode("engineer", StandardCharsets.UTF_8);
System.out.println(body);
}
}发送文件正文
BodyPublishers.ofFile(path) 会将文件作为请求正文进行流式传输,而不会将整个文件加载到内存中,非常适合上传。
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/upload"))
.header("Content-Type", "application/octet-stream")
.POST(BodyPublishers.ofFile(Path.of("data.bin")))
.build();
System.out.println("Upload request built");
}
}字节数组正文
如果您已经在内存中拥有字节,可以使用 BodyPublishers.ofByteArray(byte[]) 直接发送它们。这适用于运行时构建的二进制载荷。
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
byte[] payload = "raw-bytes".getBytes(StandardCharsets.UTF_8);
// BodyPublishers.ofByteArray(payload) would wrap these bytes
System.out.println("Payload size: " + payload.length + " bytes");
}
}受限制的请求头
出于安全考虑,客户端禁止您设置某些请求头,例如 Host、Content-Length、Connection 和 Upgrade。尝试设置这些请求头会抛出 IllegalArgumentException——它们由客户端自行管理。
整合使用
典型的 JSON POST 会结合使用正文发布器和内容类型请求头:
.POST(BodyPublishers.ofString(json)).header("Content-Type", "application/json")- 如有需要,add
.header("Authorization", "Bearer ...")
快速检查
测试您对请求正文和请求头的理解。
回顾
您已经学会了如何发送数据和控制请求头:
- BodyPublishers.ofString / ofByteArray / ofFile 用于提供请求正文。
- POST / PUT / DELETE / method(...) 用于选择 HTTP 方法。
- header(...) 和 headers(...) 用于设置请求头。
- 对于 JSON 和表单数据,请设置
Content-Type;对于令牌,请使用Authorization。 - 某些请求头(主机、内容长度)受到限制,并由客户端管理。
常见问题解答
「请求正文与标头」课时是免费的吗?
是的 — 「请求正文与标头」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「请求正文与标头」这节课中我会学到什么?
发送 POST 数据并设置标头 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「请求正文与标头」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。