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;
    }
}
时间: 2024-10-20 15:26:36

Preferred Java way to ping a HTTP Url for availability的相关文章

URL中加入BASE64加密的字符串引起的问题(java.net.MalformedURLException:Illegal character in URL)

序 昨天在做一个 Demo 的时候,由于是调用第三方的接口,采用的是 HTTP 的通信协议,按照文档上的说明,需要把参数进行加密后加入到 URL 中,但是,就是这个看似普普通通的操作,却让我着实费了很大的劲. 背景 关于 BASE64,我不想说太多,因为这是很基本的一种编码方式,或者说是加密方式.不了解的可以到我前面的博客中去看看,关于加密,前边有一个系列的文章.下面说说出现这个问题的情景. 昨天拿到一个任务,写一个 Demo,目的是查询一系列的信息,当然,需要调用一个第三方的接口,根据接口文档

Java使用zpxing.jar生成带url的二维码

第一步下载zpxing.jar包,并加载进来(网上有很多类似的jar包,这里小编使用的是谷歌提供的jar) 二维码工具类: package com.zpxing.controller; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRe

Java中的网络支持InetAddress&amp;URL

针对网络通信的不同层次,Java提供的网络功能有四大类 InetAddress:用于标识网络上的硬件资源.(说白了就是IP地址的相关信息) URL:统一资源定位符,通过URL可以直接读取或写入网络上的数据 Sockets:使用TCP协议实现网络通信的Socket相关的类 Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信.(通过在网络中发送数据报进而实现网络的通信) InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)协议. 1 package zhan

Java Web 编码问题三:URL和URI以及QueryString的编码问题

在问题之前我们先来了解一下什么是URL,URI以及QueryString,如下图1所示: 图1:URL-URI-QueryString URL:是全球资源定位符的英文缩写,如上 其中localhost:是指Domain(IP或者主机名),8080:是端口 Web服务一般是80,8080是自己测试是候用的,避免和和浏览器的端口冲突. ROOT:是ContentPath,就是虚拟路径,如果是tomcat服务器对象的是servlet.xml配置文件中的<Context path="/ROOT&q

分享Java中模拟Ping操作的一个类

似乎使用JavaPing的操作很少啊,不过我遇到了:最终解决了,在这里贴出一个中间过程中的类. import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; /** * Created by QiuJU * on 2014/9/21. */ public class SimplePing implements Runnable { private final Objec

java基础:网络编程TCP,URL

获取域名的两种方法: package com.lanqiao.java.test; import java.net.InetAddress;import java.net.UnknownHostException; public class testInetAddress { public static void main(String[] args) throws Exception { InetAddress inet=InetAddress.getByName("www.atguigu.c

Java魔法堂:URI、URL(含URL Protocol Handler)和URN

一.前言 过去一直搞不清什么是URI什么是URL,现在是时候好好弄清楚它们了!本文作为学习笔记,以便日后查询,若有纰漏请大家指正! 二.从URI说起    1. 概念 URI(Uniform Resource Identifier,统一资源标识符)以字符串来表示某种资源的统一资源标识. 格式为: [scheme:]scheme-specific-part[#fragment] [scheme:]组件 ,URI的名称空间标识. scheme-specific-part组件 ,用于标识资源,内部格式

JAVA入门学习:网站的URL重写

本文来源:http://www.zretc.com/technologyDetail/462.html Java UrlRewrite 的使用实例 URL重写 现在大部分的网站和商城都会使用到URL重写,接触到这个,也是因为正在做的电子商务商城.URL重写,是将原有的URL采用另一种规则来显示,使得用户方便访问同时也屏蔽一些信息. 在此说下它的好处,在开发过程中,经常会遇到一些带了一大堆参数的URL,这样子,一方面显得烦乱,另一方面,一些信息直接显示在URL上,会有些安全性问题.使用URL重写,

Java网络编程之InetAddress和URL

在Java中提供了专门的网络开发程序包---java.net,java的网络编程提供了两种通信协议:TCP(传输控制协议)和UDP(数据报协议). 一.IP(Internet Protocol) 与InetAddress类 1.IP简介 互联网上的每一台计算机都有一个唯一表示自己的标识,即IP地址. IP地址=网络地址+主机地址 2.InetAddress 该类主要表示IP地址,有两个子类:Inet4Address.Inet6Address,前者表示IPV4,后者表示IPV6. InetAddr