66

I am trying to parse an XML file from an HTTP URL. I want to configure a timeout of 15 seconds if the XML fetch takes longer than that, I want to report a timeout. For some reason, the setConnectTimeout and setReadTimeout do not work. Here's the code:

          URL url = new URL("http://www.myurl.com/sample.xml");
          URLConnection urlConn = url.openConnection();
          urlConn.setConnectTimeout(15000);
          urlConn.setReadTimeout(15000);
          urlConn.setAllowUserInteraction(false);         
          urlConn.setDoOutput(true);

          InputStream inStream = urlConn.getInputStream();
          InputSource input = new InputSource(inStream);

And I am catching the SocketTimeoutException.

Thanks Chris

Chris
  • 3,787
  • 13
  • 42
  • 49

5 Answers5

32

Try this:

       import java.net.HttpURLConnection;

       URL url = new URL("http://www.myurl.com/sample.xml");

       HttpURLConnection huc = (HttpURLConnection) url.openConnection();
       HttpURLConnection.setFollowRedirects(false);
       huc.setConnectTimeout(15 * 1000);
       huc.setRequestMethod("GET");
       huc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
       huc.connect();
       InputStream input = huc.getInputStream();

OR

       import org.jsoup.nodes.Document;

       Document doc = null;
       try {
           doc = Jsoup.connect("http://www.myurl.com/sample.xml").get();
       } catch (Exception e) {
           //log error
       }

And take look on how to use Jsoup: http://jsoup.org/cookbook/input/load-document-from-url

MatBanik
  • 26,356
  • 39
  • 116
  • 178
  • 1
    with Java 7 (+) it works like expected: `conn.setReadTimeout(1000*10*1); conn.setConnectTimeout(1000*10*1); // 10 seks to wait for connection` waits exactly 10 secs for a connect and for data. – Axel Amthor Feb 28 '15 at 07:18
  • 3
    This only affects the connect timeout, not the read timeout. Doesn't answer the question in any way. – user207421 Feb 01 '19 at 11:20
17

You can manually force disconnection by a Thread sleep. This is an example:

URLConnection con = url.openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
new Thread(new InterruptThread(con)).start();

then

public class InterruptThread implements Runnable {

    HttpURLConnection con;
    public InterruptThread(HttpURLConnection con) {
        this.con = con;
    }

    public void run() {
        try {
            Thread.sleep(5000); // or Thread.sleep(con.getConnectTimeout())
        } catch (InterruptedException e) {

        }
        con.disconnect();
        System.out.println("Timer thread forcing to quit connection");
    }
}
kinghomer
  • 3,021
  • 2
  • 33
  • 56
  • From documentation: void java.net.HttpURLConnection.disconnect() Indicates that other requests to the server are unlikely in the near future. Calling disconnect() should not imply that this HttpURLConnection instance can be reused for other requests. --> So the socket is not necessarily closed when disconnect() is called. – A.G. May 29 '15 at 14:40
  • 3
    Beware that this code will try to disconnect in 5 seconds anyway, even if you connected successfully and want to continue using that connection. – Fyodor Menshikov Oct 18 '17 at 10:18
14

You can set timeouts for all connections made from the jvm by changing the following System-properties:

System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");

Every connection will time out after 10 seconds.

Setting 'defaultReadTimeout' is not needed, but shown as an example if you need to control reading.

Arjen Rodenhuis
  • 199
  • 1
  • 3
9

I have used similar code for downloading logs from servers. I debug my code and discovered that implementation of URLConnection which is returned is sun.net.www.protocol.http.HttpURLConnection.

Abstract class java.net.URLConnection have two attributes connectTimeout and readTimeout and setters are in abstract class. Believe or not implementation sun.net.www.protocol.http.HttpURLConnection have same attributes connectTimeout and readTimeout without setters and attributes from implementation class are used in getInputStream method. So there is no use of setting connectTimeout and readTimeout because they are never used in getInputStream method. In my opinion this is bug in sun.net.www.protocol.http.HttpURLConnection implementation.

My solution for this was to use HttpClient and Get request.

dino.keco
  • 1,401
  • 1
  • 12
  • 18
  • 3
    While this may be true depending on the Java version, the Java 6.0 API states: [Some non-standard implementation of this method ignores the specified timeout. To see the read timeout set, please call getReadTimeout().](http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#setReadTimeout(int)) – David O'Meara Jan 18 '12 at 01:14
  • Both these attributes have worked for me for over 20 years. – user207421 Feb 01 '19 at 11:22
1

Are you on Windows? The underlying socket implementation on Windows seems not to support the SO_TIMEOUT option very well. See also this answer: setSoTimeout on a client socket doesn't affect the socket

Community
  • 1
  • 1
xpmatteo
  • 11,156
  • 3
  • 26
  • 25