zoukankan      html  css  js  c++  java
  • Preferred Java way to ping a HTTP Url for availability

    I need a monitor class that regularly checks whether a given HTTP URL is available. I can take care of the "regularly" part using the Spring TaskExecutor abstraction, so that's not the topic here. The Question is:What is the preferred way to ping a URL in java?

    Here is my current code as a starting point:

    package org.javalobby.tnt.net;
    
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    public class DnsTest {
        public static void main(String[] args) {
            String url = "http://www.baidu.com";
            try{
                final URLConnection connection = new URL(url).openConnection();
                connection.connect();
                System.out.println("Service " + url + " available, yeah!");
            } catch(final MalformedURLException e){
                throw new IllegalStateException("Bad URL: " + url, e);
            } catch(final IOException e){
                System.out.println("Service " + url + " unavailable, oh no!  " + e);
            }
        }
    
    }
    1. Is this any good at all (will it do what I want?)
    2. Do I have to somehow close the connection?
    3. I suppose this is a GET request. Is there a way to send HEAD instead?

    Is this any good at all (will it do what I want?)

    You can do so. Another feasible way is using java.net.Socket.

            url = "www.baidu.com";
            Socket socket = null;
            boolean reachable = false;
            try {
                socket = new Socket(url, 80);
                reachable = true;
                System.out.println("true");
            } finally {            
                if (socket != null) try { socket.close(); } catch(IOException e) {}
            }

    There's also the InetAddress#isReachable():

    boolean reachable = InetAddress.getByName(hostname).isReachable();

    This however doesn't explicitly test port 80. You risk to get false negatives due to a Firewall blocking other ports.

     Do I have to somehow close the connection?

    No, you don't explicitly need. It's handled and pooled under the hoods.

    I suppose this is a GET request. Is there a way to send HEAD instead?

    You can cast the obtained URLConnection to HttpURLConnection and then use setRequestMethod() to set the request method. However, you need to take into account that some poor webapps or homegrown servers may return HTTP 405 error for a HEAD (i.e. not available, not implemented, not allowed) while a GET works perfectly fine. But, those are pretty rare cases.

    Update as per the comments: connecting a host only informs if the host is available, not if the content is available. You seem to be more interested in the content since it can as good happen that a webserver has started without problems, but the webapp failed to deploy during server's start. This will however usually not cause the entire server to go down. So you'd like to determine the HTTP response code.

        url = "http://www.baidu.com";
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("HEAD");
            int responseCode = connection.getResponseCode();
            if (responseCode != 200) {
                // Not OK.
                System.out.println("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

    For more detail about response status codes see RFC 2616 section 10. Calling connect() is by the way not needed if you're determining the response data. It will implicitly connect.

    For future reference, here's a complete example in flavor of an utility method, also taking account with timeouts:

    /**
     * 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 ping(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;
        }
    }
  • 相关阅读:
    【python】新创建一个列表,并向内添加元素 and 列表中查询最大值位置和最小值位置
    【python】python从命令行读入参数
    【开发环境安装笔记 】微软Visual Studio2012中文旗舰版(完美破解版)
    【Python笔记】Python读取word文本操作详解
    【安装---WIN7--cnpm】win7实测安装npm,cnpm
    【安装---WIN7--Vuejs】Vue.js 安装及其环境搭建
    【安装---WIN7--nodejs】win7安装 nodejs,npm
    【安装--达梦】Linux(中科方德服务器版4.0)安装达梦数据库V8
    【安装—ES】ES数据库安装6.6b版本
    【centos系统--安装--异常】server重装系统后,远程登录提示主机密钥验证失败的解决办法
  • 原文地址:https://www.cnblogs.com/ghgyj/p/4039367.html
Copyright © 2011-2022 走看看