1. 概述

在 Java 编程中,有时我们需要在访问某个 URL 之前,确认该地址是否真的存在对应的资源。这种检查常用于资源可用性检测、服务健康检查等场景。

本文将介绍如何使用 Java 中的 HttpURLConnection 来判断一个 URL 是否存在,并通过 GETHEAD 两种 HTTP 方法进行演示。


2. URL 是否存在?

判断一个 URL 是否存在,最常用的方式是向该 URL 发起 HTTP 请求,并根据返回的 HTTP 状态码 来判断。

通常来说:

  • 200 OK:表示资源存在
  • 404 Not Found:表示资源不存在
  • ⚠️ 3xx:表示重定向,需根据业务逻辑决定是否跟进
  • ⚠️ 405 Method Not Allowed:表示服务器不支持某些请求方法(如 HEAD)

3. 使用 GET 请求

使用 GET 请求是最直接的方法。Java 提供了 HttpURLConnection 类来发起 HTTP 请求。

示例代码如下:

URL url = new URL("https://httpbin.org/status/200");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_OK, responseCode);

如果目标 URL 不存在,通常会返回 404

URL url = new URL("https://httpbin.org/status/404");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, responseCode);

📌 注意:HttpURLConnection 默认使用 GET 方法,所以无需显式设置。


4. 使用 HEAD 请求

HEAD 请求和 GET 类似,但 不会返回响应体(body),仅返回响应头(headers)和状态码。

这可以减少带宽消耗,提升响应速度,是一个更高效的选择。

示例代码如下:

URL url = new URL("https://httpbin.org/status/200");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
huc.setRequestMethod("HEAD");

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_OK, responseCode);

同样地,当资源不存在时:

URL url = new URL("https://httpbin.org/status/404");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
huc.setRequestMethod("HEAD");

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, responseCode);

📌 踩坑提醒:

虽然大多数现代服务器都支持 HEAD 方法,但一些老旧或自研的服务器可能不支持,会返回 405 Method Not Allowed 错误。使用时请注意兼容性。


5. 处理重定向

当 URL 被移动后,服务器可能会返回 3xx 状态码并附带新的 URL 地址。默认情况下,HttpURLConnection 会自动跟进这些重定向。

但在某些场景下(如判断原始 URL 是否有效),我们可能 不希望自动跳转

可以通过以下方式关闭全局重定向:

URL url = new URL("https://httpbin.org/status/200");
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection huc = (HttpURLConnection) url.openConnection();

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_OK, responseCode);

也可以只为单个连接关闭重定向:

URL url = new URL("https://httpbin.org/status/200");
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
huc.setInstanceFollowRedirects(false);

int responseCode = huc.getResponseCode();

Assert.assertEquals(HttpURLConnection.HTTP_OK, responseCode);

📌 建议:

是否跟进重定向应根据实际业务需求决定。如果目标是验证原始链接是否可用,建议关闭重定向。


6. 总结

判断 URL 是否存在,本质上是通过 HTTP 请求获取状态码进行判断。以下是本文的几个关键点:

方法 是否返回响应体 是否节省带宽 兼容性
GET ✅ 是 ❌ 否 ✅ 好
HEAD ❌ 否 ✅ 是 ⚠️ 可能存在兼容性问题

📌 推荐做法:

优先使用 HEAD 方法检查 URL 是否存在,效率更高。如果遇到兼容性问题,再回退到 GET 方法。


完整示例代码可在 GitHub 项目 中找到。


原始标题:Checking if a URL Exists in Java