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