Це взагалі користь (чи буде це робити те, що я хочу?)
Ви можете це зробити. Ще один здійсненний спосіб - використання java.net.Socket
.
public static boolean pingHost(String host, int port, int timeout) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), timeout);
return true;
} catch (IOException e) {
return false; // Either timeout or unreachable or failed DNS lookup.
}
}
Є також InetAddress#isReachable()
:
boolean reachable = InetAddress.getByName(hostname).isReachable();
Однак це чітко не перевіряє порт 80. Ви ризикуєте отримати помилкові негативи через брандмауер, що блокує інші порти.
Чи треба якось перервати зв’язок?
Ні, вам явно не потрібно. Це обробляється і об'єднується під капотами.
Я припускаю, що це GET-запит. Чи є спосіб надіслати HEAD замість цього?
Ви можете привести отриманий URLConnection
в HttpURLConnection
і потім використовувати , setRequestMethod()
щоб задати метод запиту. Однак вам потрібно врахувати, що деякі погані веб-сервери або домашні сервери можуть повернути помилку HTTP 405 для HEAD (тобто не доступна, не реалізована, не дозволена), в той час як GET працює чудово. Використання GET є більш надійним у випадку, якщо ви плануєте перевірити посилання / ресурси, а не домени / хости.
Тестування сервера на наявність у моєму випадку недостатньо, мені потрібно перевірити URL-адресу (веб-версія може не розгортатися)
Дійсно, підключення хоста інформує лише про те, якщо хост доступний, а не якщо вміст доступний. Так може статися, що веб-сервер запустився без проблем, але веб-сервер не вдалося розгорнути під час запуску сервера. Однак, зазвичай, це не призведе до того, що весь сервер знизиться. Ви можете визначити це, перевіривши, чи відповідає код відповіді HTTP 200.
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
// Not OK.
}
// < 100 is undetermined.
// 1nn is informal (shouldn't happen on a GET/HEAD)
// 2nn is success
// 3nn is redirect
// 4nn is client error
// 5nn is server error
Детальніше про коди статусу відповіді див. У розділі 10 RFC 2616 . Дзвінки connect()
, до речі, не потрібні, якщо ви визначаєте дані відповіді. Це неявно з'єднається.
Для подальшого ознайомлення, ось повний приклад аромату корисного методу, який також враховує тайм-аути:
/**
* Pings a HTTP URL. This effectively sends a HEAD request and returns <code>true</code> if the response code is in
* the 200-399 range.
* @param url The HTTP URL to be pinged.
* @param timeout The timeout in millis for both the connection timeout and the response read timeout. Note that
* the total timeout is effectively two times the given timeout.
* @return <code>true</code> if the given HTTP URL has returned response code 200-399 on a HEAD request within the
* given timeout, otherwise <code>false</code>.
*/
public static boolean pingURL(String url, int timeout) {
url = url.replaceFirst("^https", "http"); // Otherwise an exception may be thrown on invalid SSL certificates.
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();
return (200 <= responseCode && responseCode <= 399);
} catch (IOException exception) {
return false;
}
}