Sea*_*oyd 157 java url http ping
我需要一个监视器类来定期检查给定的HTTP URL是否可用.我可以使用Spring TaskExecutor抽象来处理"常规"部分,因此这不是主题.问题是:在java中ping URL的首选方法是什么?
这是我当前的代码作为起点:
try {
final URLConnection connection = new URL(url).openConnection();
connection.connect();
LOG.info("Service " + url + " available, yeah!");
available = true;
} catch (final MalformedURLException e) {
throw new IllegalStateException("Bad URL: " + url, e);
} catch (final IOException e) {
LOG.info("Service " + url + " unavailable, oh no!", e);
available = false;
}
Run Code Online (Sandbox Code Playgroud)
GET
请求.有没有办法发送HEAD
?Bal*_*usC 261
这有什么好处(它会做我想做的吗?)
你可以这样做.另一种可行的方法是使用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.
}
}
Run Code Online (Sandbox Code Playgroud)
boolean reachable = InetAddress.getByName(hostname).isReachable();
Run Code Online (Sandbox Code Playgroud)
但是,这并未明确测试端口80.由于防火墙阻止其他端口,您可能会出现漏报.
我必须以某种方式关闭连接吗?
不,你没有明确需要.它被处理和汇集在引擎盖下.
我想这是一个GET请求.有没有办法发送HEAD?
您可以将获取的转换URLConnection
为HttpURLConnection
然后用于setRequestMethod()
设置请求方法.但是,您需要考虑到一些糟糕的Web应用程序或自行开发的服务器可能会为HEAD 返回HTTP 405错误(即不可用,未实现,不允许),而GET工作正常.如果您打算验证链接/资源而不是域/主机,则使用GET更可靠.
在我的情况下测试服务器的可用性是不够的,我需要测试URL(可能没有部署webapp)
实际上,连接主机只会通知主机是否可用,而不是内容可用.Web服务器启动时没有问题,但是在服务器启动期间无法部署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
Run Code Online (Sandbox Code Playgroud)
有关响应状态代码的更多详细信息,请参阅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;
}
}
Run Code Online (Sandbox Code Playgroud)
YoK*_*YoK 17
而不是使用URLConnection 通过调用URL对象上的openConnection()来使用HttpURLConnection.
然后使用getResponseCode()会在您从连接中读取后为您提供HTTP响应.
这是代码:
HttpURLConnection connection = null;
try {
URL u = new URL("http://www.google.com/");
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("HEAD");
int code = connection.getResponseCode();
System.out.println("" + code);
// You can determine on HTTP return code received. 200 is success.
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
Run Code Online (Sandbox Code Playgroud)
还要检查类似的问题如何检查URL是否存在或使用Java返回404?
希望这可以帮助.