주어진 HTTP URL이 사용 가능한지 정기적으로 확인하는 모니터 클래스가 필요합니다. Spring TaskExecutor 추상화를 사용하여 “일반적으로”부분을 처리 할 수 있으므로 여기서는 주제가 아닙니다. 문제는 다음과 같습니다. java에서 URL을 ping하는 기본 방법은 무엇입니까?
다음은 현재 코드입니다.
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;
}
- 이게 좋은가요? (원하는대로할까요?)
- 어떻게 든 연결을 닫아야합니까?
- 이것이
GET
요청 이라고 생각합니다 .HEAD
대신 보낼 방법이 있습니까?
답변
이것은 전혀 좋지 않은가 (내가 원하는 것을 할 것인가?)
그렇게 할 수 있습니다. 다른 가능한 방법은을 사용하는 것 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()
요청 방법을 설정하는 데 사용할 수 있습니다 . 그러나 GET이 완벽하게 작동하는 동안 일부 불량 웹 응용 프로그램 또는 자체 개발 서버 에서 HEAD에 대해 HTTP 405 오류 (즉, 사용할 수 없거나 구현되지 않았으며 허용되지 않음)를 반환 할 수 있다는 점을 고려해야 합니다. 도메인 / 호스트가 아닌 링크 / 리소스를 확인하려는 경우 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 섹션 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;
}
}
답변
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();
}
}
비슷한 질문 을 확인하십시오 URL이 존재하는지 확인하거나 Java로 404를 반환하는 방법은 무엇입니까?
도움이 되었기를 바랍니다.
답변
당신은 또한 사용할 수 HttpURLConnection의을 (예 : HEAD에) 당신이 요청 방법을 설정할 수있는. 다음 은 요청을 보내고 응답을 읽고 연결을 끊는 방법을 보여주는 예 입니다.
답변
다음 코드 HEAD
는 웹 사이트 사용 가능 여부 확인 요청을 수행합니다 .
public static boolean isReachable(String targetUrl) throws IOException
{
HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(
targetUrl).openConnection();
httpUrlConnection.setRequestMethod("HEAD");
try
{
int responseCode = httpUrlConnection.getResponseCode();
return responseCode == HttpURLConnection.HTTP_OK;
} catch (UnknownHostException noInternetConnection)
{
return false;
}
}
답변
여기서 작가는 이것을 제안합니다.
public boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
} catch (IOException | InterruptedException e) { e.printStackTrace(); }
return false;
}
가능한 질문
- 이거 정말 빠르지? 네, 아주 빠릅니다!
- 어쨌든 요청하고 싶은 내 페이지를 핑 (ping) 할 수 없습니까? 확실한! “사용 가능한 인터넷 연결”과 도달 가능한 자신의 서버를 구별하려면 두 가지를 모두 확인할 수도 있습니다. DNS가 다운되면 어떻게됩니까? Google DNS (예 : 8.8.8.8)는 세계에서 가장 큰 퍼블릭 DNS 서비스입니다. 2013 년 현재 하루 1,300 억 건의 요청을 처리합니다. 응답하지 않는 앱은 아마도 오늘의 이야기가 아닐 것입니다.
링크를 읽으십시오. 아주 좋아 보인다
편집 : 내 경험에 따르면이 방법만큼 빠르지 않습니다.
public boolean isOnline() {
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
그것들은 조금 다르지만 인터넷 연결을 확인하는 기능에서 첫 번째 방법은 연결 변수로 인해 느려질 수 있습니다.
답변
이런 종류의 의미를 가진 Restlet 프레임 워크 사용을 고려하십시오. 강력하고 유연합니다.
코드는 다음과 같이 간단 할 수 있습니다.
Client client = new Client(Protocol.HTTP);
Response response = client.get(url);
if (response.getStatus().isError()) {
// uh oh!
}