核心概念
无论使用哪种方法,通过域名请求的背后原理都是一样的:

- DNS 解析:Java 程序首先需要将人类可读的域名(
www.google.com)转换成机器可读的 IP 地址(250.191.78),这个过程由操作系统或 Java 的网络系统自动完成。 - 建立连接:一旦获得了 IP 地址,Java 程序就会使用这个 IP 地址和指定的端口号(如 HTTP 的 80 或 HTTPS 的 443)与目标服务器建立一个网络连接。
- 发送请求:程序构造一个 HTTP/HTTPS 请求报文(包含请求方法、路径、头信息等),并通过建立的连接发送给服务器。
- 接收响应:程序读取服务器返回的响应报文(包含状态码、响应头和响应体)。
- 处理数据:解析响应报文,提取出需要的数据(如 JSON、HTML、图片等)。
下面我们来看几种实现这个过程的具体方式。
使用 HttpURLConnection (Java 标准库)
这是 Java 自带的传统方式,无需添加任何第三方依赖,它比较底层,使用起来略显繁琐,但对于简单的请求来说足够了。
示例代码:发送一个 GET 请求
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpURLConnectionExample {
public static void main(String[] args) {
// 目标域名
String urlString = "https://www.baidu.com";
try {
// 1. 创建 URL 对象
URL url = new URL(urlString);
// 2. 打开连接,获取 HttpURLConnection 实例
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 3. 设置请求方法
connection.setRequestMethod("GET");
// 4. 设置请求头 (可选)
connection.setRequestProperty("User-Agent", "Java-HttpURLConnection-Example");
connection.setRequestProperty("Accept", "text/html");
// 5. 获取响应码
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
// 6. 判断请求是否成功 (2xx 表示成功)
if (responseCode == HttpURLConnection.HTTP_OK) {
// 7. 读取响应数据
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 8. 打印响应内容
System.out.println("Response Content:");
System.out.println(response.toString());
} else {
System.out.println("GET request failed. Response Code: " + responseCode);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
优缺点:
- 优点:无需额外依赖,随 JDK 一起发布。
- 缺点:API 过时,代码冗长,处理复杂请求(如异步、上传文件、JSON 处理)非常麻烦。
使用 Apache HttpClient (强烈推荐)
这是目前业界最流行、功能最强大的 HTTP 客户端库之一,被广泛应用于各种 Java 项目中,它功能全面,API 设计现代,性能优异。

你需要在你的项目中添加 Maven 依赖:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version> <!-- 请使用最新版本 -->
</dependency>
示例代码:发送一个 GET 请求
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.net.URISyntaxException;
public class HttpClientExample {
public static void main(String[] args) {
// 1. 创建 HttpClient 实例 (推荐使用 CloseableHttpClient)
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 2. 创建 HttpGet 请求对象
// 可以直接使用字符串,也可以使用 URIBuilder 构建更复杂的 URL
HttpGet request = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");
// 3. 设置请求头 (可选)
request.setHeader("Accept", "application/json");
request.setHeader("User-Agent", "Java-HttpClient-Example");
System.out.println("Executing request: " + request.getMethod() + " " + request.getUri());
// 4. 执行请求,获取响应
try (CloseableHttpResponse response = httpClient.execute(request)) {
// 5. 获取响应实体
HttpEntity entity = response.getEntity();
// 6. 打印响应状态码
System.out.println("Response status: " + response.getCode());
// 7. 如果响应实体不为空,则处理其内容
if (entity != null) {
// 将响应实体内容转换为字符串
String result = EntityUtils.toString(entity);
System.out.println("Response Body:");
System.out.println(result);
// 重要:确保完全消耗实体内容,以便连接可以被重用
EntityUtils.consume(entity);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
优缺点:
- 优点:功能强大(支持异步、连接池、重试机制等)、API 现代流畅、社区活跃、文档完善。
- 缺点:需要引入第三方依赖。
使用 OkHttp (现代且高效)
OkHttp 是另一个非常流行的 HTTP 客户端,以其高性能、简洁的 API 和对 HTTP/2 的原生支持而闻名,它在 Android 开发中几乎是标配,在 Java 后端开发中也越来越受欢迎。
添加 Maven 依赖:

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version> <!-- 请使用最新版本 -->
</dependency>
示例代码:发送一个 GET 请求
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
public static void main(String[] args) {
// 1. 创建 OkHttpClient 实例 (推荐使用单例模式)
OkHttpClient client = new OkHttpClient();
// 2. 创建 Request 对象
Request request = new Request.Builder()
.url("https://api.github.com/users/octocat")
.header("User-Agent", "Java-OkHttp-Example")
.build();
// 3. 使用 client 发起请求并获取响应
try (Response response = client.newCall(request).execute()) {
// 4. 判断是否成功 (isSuccessful() 检查 2xx 状态码)
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
// 5. 获取并打印响应体
System.out.println("Response Body:");
System.out.println(response.body().string());
// 注意:response.body().string() 只能被调用一次,因为它会消耗流。
// 如果需要多次使用,应先将其读取并存储起来。
} catch (IOException e) {
e.printStackTrace();
}
}
}
优缺点:
- 优点:API 极其简洁易用、性能高(默认支持 HTTP/2 和连接池)、支持 WebSocket。
- 缺点:需要引入第三方依赖。
使用 Spring RestTemplate 或 WebClient (Spring 生态)
如果你的项目已经使用了 Spring 框架,那么使用它自带的 HTTP 客户端是最佳选择,它们与 Spring 生态无缝集成。
RestTemplate (传统方式,现已不推荐用于新项目)
import org.springframework.web.client.RestTemplate;
public class RestTemplateExample {
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
// 直接使用域名发起 GET 请求,并自动将返回的 JSON 映射为 Map
String url = "https://jsonplaceholder.typicode.com/todos/1";
String result = restTemplate.getForObject(url, String.class);
System.out.println(result);
}
}
WebClient (现代异步方式,推荐)
WebClient 是 Spring 5 引入的、基于响应式编程的 HTTP 客户端,支持非阻塞 I/O,性能更高。
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class WebClientExample {
public static void main(String[] args) {
// 创建 WebClient 实例
WebClient webClient = WebClient.create();
// 定义目标 URL
String url = "https://api.github.com/users/octocat";
// 发起异步 GET 请求
Mono<String> responseMono = webClient.get()
.uri(url)
.retrieve() // 获取响应
.bodyToMono(String.class); // 将响应体转为 Mono<String>
// 阻塞并获取结果 (在主线程中,为了简单演示)
String result = responseMono.block();
System.out.println(result);
}
}
优缺点:
- 优点:与 Spring 框架深度集成,支持自动转换 JSON/XML、支持异步编程 (
WebClient)。 - 缺点:强依赖于 Spring 生态,不适合在非 Spring 项目中使用。
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
HttpURLConnection |
无需依赖,标准库 | API 过时,功能弱,代码繁琐 | 简单的脚本、小型应用、不想引入依赖的项目 |
| Apache HttpClient | 功能强大,稳定,性能好,社区活跃 | 需要引入依赖 | 通用首选,适合绝大多数 Java 项目,特别是企业级应用 |
| OkHttp | API 简洁,性能高,支持 HTTP/2 | 需要引入依赖 | 现代推荐,尤其适合对性能有要求的项目,Android 开发首选 |
Spring RestTemplate |
与 Spring 集成,使用简单 | 已过时,同步阻塞 | 旧版 Spring 项目维护 |
Spring WebClient |
异步非阻塞,性能高,现代 API | 依赖 Spring 5+,响应式编程学习曲线 | 新版 Spring 项目首选,特别是微服务、高并发场景 |
如何选择?
- 如果你是初学者或在做一个小练习:从
HttpURLConnection开始,了解底层原理。 - 如果你在开发一个标准的 Java 后端项目:强烈推荐 Apache HttpClient 或 OkHttp,两者都是顶级的,选择哪个更多取决于团队偏好,OkHttp 的 API 更为优雅。
- 如果你的项目已经使用了 Spring 框架:直接使用
WebClient(新项目) 或RestTemplate(旧项目),这是最省心、最高效的方式。
