Это вообще хорошо (будет ли то, что я хочу?)
Вы можете сделать это. Другой возможный способ использования 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
Для получения более подробной информации о кодах состояния ответа см. RFC 2616 раздел 10 . Вызов 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;
}
}