È buono (farà quello che voglio?)
Puoi farlo. Un altro modo fattibile sta usando 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.
}
}
C'è anche il InetAddress#isReachable()
:
boolean reachable = InetAddress.getByName(hostname).isReachable();
Questo, tuttavia, non verifica esplicitamente la porta 80. Rischi di ottenere falsi negativi a causa di un firewall che blocca altre porte.
Devo in qualche modo chiudere la connessione?
No, non hai esplicitamente bisogno. È gestito e raggruppato sotto i cappucci.
Suppongo che questa sia una richiesta GET. C'è un modo per inviare HEAD invece?
È possibile trasmettere il ottenuto URLConnection
a HttpURLConnection
e quindi utilizzare setRequestMethod()
per impostare il metodo di richiesta. Tuttavia, è necessario tenere conto del fatto che alcune applicazioni web o server poveri possono restituire l' errore HTTP 405 per un HEAD (ovvero non disponibile, non implementato, non consentito) mentre un GET funziona perfettamente. L'uso di GET è più affidabile nel caso in cui si intenda verificare collegamenti / risorse non domini / host.
Testare la disponibilità del server non è abbastanza nel mio caso, devo testare l'URL (la webapp potrebbe non essere distribuita)
In effetti, la connessione di un host informa solo se l'host è disponibile, non se il contenuto è disponibile. Può anche succedere che un server web sia stato avviato senza problemi, ma la webapp non è stata distribuita all'avvio del server. Questo, tuttavia, di solito non causa l'interruzione dell'intero server. Puoi determinarlo controllando se il codice di risposta 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
Per maggiori dettagli sui codici di stato della risposta, consultare la sezione 10 di RFC 2616 . La chiamata non connect()
è assolutamente necessaria se si determinano i dati di risposta. Si collegherà implicitamente.
Per riferimento futuro, ecco un esempio completo nel sapore di un metodo di utilità, tenendo conto anche dei timeout:
/**
* 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;
}
}