Ist das überhaupt gut (wird es tun, was ich will?)
Sie können dies tun. Ein anderer möglicher Weg ist die Verwendung 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.
}
}
Es gibt auch die InetAddress#isReachable()
:
boolean reachable = InetAddress.getByName(hostname).isReachable();
Dies testet Port 80 jedoch nicht explizit. Es besteht die Gefahr, dass aufgrund einer Firewall, die andere Ports blockiert, falsche Negative angezeigt werden.
Muss ich die Verbindung irgendwie schließen?
Nein, das brauchen Sie nicht explizit. Es wird unter den Hauben gehandhabt und gepoolt.
Ich nehme an, dies ist eine GET-Anfrage. Gibt es eine Möglichkeit, stattdessen HEAD zu senden?
Sie können das erhaltene URLConnection
umwandeln HttpURLConnection
und dann verwenden setRequestMethod()
, um die Anforderungsmethode festzulegen. Sie müssen jedoch berücksichtigen, dass einige schlechte Webanwendungen oder selbst entwickelte Server möglicherweise einen HTTP 405-Fehler für einen HEAD zurückgeben (dh nicht verfügbar, nicht implementiert, nicht zulässig), während ein GET einwandfrei funktioniert. Die Verwendung von GET ist zuverlässiger, wenn Sie Links / Ressourcen überprüfen möchten, nicht Domänen / Hosts.
Das Testen des Servers auf Verfügbarkeit reicht in meinem Fall nicht aus. Ich muss die URL testen (die Webanwendung wird möglicherweise nicht bereitgestellt).
In der Tat informiert das Verbinden eines Hosts nur, wenn der Host verfügbar ist, nicht, wenn der Inhalt verfügbar ist. Es kann genauso gut passieren, dass ein Webserver ohne Probleme gestartet wurde, die Webanwendung jedoch beim Start des Servers nicht bereitgestellt werden konnte. Dies führt jedoch normalerweise nicht dazu, dass der gesamte Server ausfällt. Sie können dies feststellen, indem Sie überprüfen, ob der HTTP-Antwortcode 200 lautet.
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
Weitere Informationen zu Antwortstatuscodes finden Sie in Abschnitt 10 von RFC 2616 . Ein Anruf connect()
ist übrigens nicht erforderlich, wenn Sie die Antwortdaten ermitteln. Es wird implizit eine Verbindung hergestellt.
Zum späteren Nachschlagen finden Sie hier ein vollständiges Beispiel für eine Dienstprogrammmethode, das auch Zeitüberschreitungen berücksichtigt:
/**
* 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;
}
}