0Pricing
Java Academy · 课时

java.net.http.HttpClient

发送同步请求

java.net.http.HttpClient 是 CoddyKit 上的免费 Java Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

现代 HTTP 客户端

从 Java 11 开始,JDK 在 java.net.http 包中提供了现代 HTTP 客户端。它用简洁、流畅的 API 替代了旧的 HttpURLConnection,并支持 HTTP/1.1 和 HTTP/2。

三个核心类型是:

  • HttpClient — 发送请求并管理配置(超时、代理、重定向)。
  • HttpRequest — 对要发送内容的不可变描述。
  • HttpResponse — 响应结果,包括状态、标头和正文。

创建 HttpClient

您可以使用静态 newBuilder() 方法构建客户端。一个客户端可以重复用于发送多个请求,并且是线程安全的。

这里我们将 HTTP/2 和连接超时配置好。要快速创建默认实例,也可以使用 newHttpClient()。

import java.net.http.HttpClient;
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .connectTimeout(Duration.ofSeconds(10))
            .build();
        System.out.println("Client version: " + client.version());
    }
}

构建请求

HttpRequest 是不可变的,并通过流式构建器构建。至少需要提供一个 URI;默认情况下,它会执行 GET。

您可以使用 URI.create(...) 将字符串转换为 URI。

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/data"))
            .GET()
            .build();
        System.out.println("Method: " + request.method());
        System.out.println("URI: " + request.uri());
    }
}

同步发送

send 方法会阻塞调用线程,直到收到响应。它需要一个 BodyHandler,用于告知客户端如何解释响应正文。

BodyHandlers.ofString() 会将正文读入 String。

import java.net.URI;
import java.net.http.*;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com"))
            .build();
        HttpResponse<String> response =
            client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("Status: " + response.statusCode());
    }
}

读取状态码

响应通过 statusCode() 提供一个 int 类型的状态码。2xx 范围内的代码表示成功,3xx 表示重定向,4xx 表示客户端错误,5xx 表示服务器错误。

请注意:HTTP 客户端不会因 4xx/5xx 响应抛出异常——您必须自行检查状态码。

public class Main {
    public static void main(String[] args) {
        int status = 404;
        String label;
        if (status >= 200 && status < 300) label = "Success";
        else if (status >= 300 && status < 400) label = "Redirect";
        else if (status >= 400 && status < 500) label = "Client error";
        else label = "Server error";
        System.out.println(status + " -> " + label);
    }
}

读取正文

使用 BodyHandlers.ofString() 时,response.body() 会返回一个 String。此外还有用于字节、文件和流的其他处理器(稍后介绍)。

此代码片段模拟了您会收到的正文内容。

public class Main {
    public static void main(String[] args) {
        String body = "{\"message\":\"hello\"}";
        System.out.println("Body length: " + body.length());
        System.out.println("Body: " + body);
    }
}

处理重定向

默认情况下,客户端不会跟随重定向。您可以通过构建器上的 followRedirects(...) 进行配置。

HttpClient.Redirect 中的选项包括 NEVER、ALWAYS 和 NORMAL(除从 HTTPS 降级到 HTTP 的情况外均会跟随)。

import java.net.http.HttpClient;

public class Main {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newBuilder()
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build();
        System.out.println("Redirect policy: " + client.followRedirects());
    }
}

为每个请求设置超时

连接超时设置在客户端上。请求超时(等待响应的时长)则通过请求上的 timeout(...) 设置。

如果超时,请求会抛出 HttpTimeoutException。

import java.net.URI;
import java.net.http.HttpRequest;
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com"))
            .timeout(Duration.ofSeconds(5))
            .build();
        System.out.println("Timeout set: " + request.timeout().isPresent());
    }
}

检查响应头

响应包含一个可通过 headers() 访问的 HttpHeaders 对象。请求头查找不区分大小写,并且可能返回多个值,因此 firstValue(...) 会返回一个 Optional<String>。

import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        // Simulating a header lookup result
        Optional<String> contentType = Optional.of("application/json");
        System.out.println("Content-Type: " + contentType.orElse("unknown"));
    }
}

受检异常

同步 send 会声明两个受检异常:

  • 输入/输出异常 — 网络或协议失败。
  • InterruptedException — 被阻塞的线程遭到中断。

您必须捕获或声明这两个异常。异步调用(下一课)会通过返回异步结果对象来避免这一点。

import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            // client.send(...) would go here
            throw new IOException("connection refused");
        } catch (IOException e) {
            System.out.println("Network problem: " + e.getMessage());
        }
    }
}

可复用的客户端

最佳实践:创建一个 HttpClient,并在整个应用中复用它。它会复用连接,并且完全支持线程安全。

每次请求都创建新客户端会浪费资源,也会使 HTTP/2 多路复用失去作用。

import java.net.http.HttpClient;

public class Main {
    private static final HttpClient SHARED = HttpClient.newHttpClient();

    public static void main(String[] args) {
        System.out.println("Shared client ready: " + (SHARED != null));
    }
}

快速检查

测试您对同步 HTTP 客户端的理解。

回顾

您已经学习了 JDK HTTP 客户端的基础知识:

  • HttpClient.newBuilder() 用于配置版本、超时和重定向;请复用同一个实例。
  • HttpRequest.newBuilder().uri(...).GET() 用于构建不可变请求。
  • client.send(request, BodyHandlers.ofString()) 会阻塞并返回一个 HttpResponse<String>。
  • 使用 statusCode()、body() 和 headers() 读取结果。
  • 非 2xx 状态码不会抛出异常——请自行检查。

常见问题解答

「java.net.http.HttpClient」课时是免费的吗?

是的 — 「java.net.http.HttpClient」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「java.net.http.HttpClient」这节课中我会学到什么?

发送同步请求 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「java.net.http.HttpClient」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

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