Является ли это какой-то толк (это будет делать то, что я хочу?)
Вы можете сделать это. Другим возможным способом является использование 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 error для HEAD (т. Е. Недоступно, не реализовано, не разрешено), в то время как GET работает отлично. Использование GET более надежно, если вы намерены проверять ссылки/ресурсы, а не домены/хосты.
Тестирование сервера на доступность не хватает в моем случае, мне нужно, чтобы проверить URL (веб-приложение не может быть развернуто)
Действительно, подключение хост только информирует если хост доступен, а не если контент доступен. Вполне возможно, что веб-сервер запущен без проблем, но webapp не удалось развернуть во время запуска сервера. Однако это, как правило, не приведет к тому, что весь сервер снизится. Вы можете определить, что путем проверки, если код ответа 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 section 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;
}
}
Спасибо за детали, ответы, подобные этим, делают SO прекрасным местом. Тестирование сервера для доступности недостаточно в моем случае, мне нужно проверить URL-адрес (webapp не может быть развернут), поэтому я буду придерживаться HttpURLConnection. О HEAD не является хорошим тестом: это хороший метод, если я знаю, что целевой URL поддерживает HEAD, я проверю это. –
Если это функциональное требование, то «HttpURLConnection» - лучший способ. Вам также хотелось бы определить код ответа. Вы также можете сделать это с помощью 'Socket', но это только добавляет многословие и требует знания спецификации HTTP. – BalusC
Можно получить ** java.io.IOException: неожиданный конец потока ** на некоторых серверах, чтобы исправить его, вам нужно добавить connection.setRequestProperty («Accept-Encoding», «musixmatch»); Известная проблема и сообщается на [code.google.com] (https://code.google.com/p/android/issues/detail?id=24672) –