0Pricing
Java Academy · 课时

请求正文与标头

发送 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. java.net.http.HttpClient
  2. 异步请求
  3. 请求正文与标头
  4. 处理响应
← 返回 Java Academy