18

I am using the javax.xml.soap API (javax.xml.soap.SOAPConnectionFactory, javax.xml.soap.SOAPConnection, and friends) to make a web service call to a remote server, for the most part with great success.

However, sometimes there is a problem and the program gets stuck reading forever.

To address this, I'd like to add a read timeout.

I found several ways it might be possible to achieve this, but they all seemed pretty bad.

So my question to the community is: What is the best way to implement a read timeout behaviour when using the javax.xml.soap API to make a call?

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62
  • Hi Samuel Please look into question below as it is somewhat with same context as your question. Hope you'll be able to suggest something here https://stackoverflow.com/questions/47861767/http-connect-timeout-and-read-timeout-for-urlstreamhandler-with-saaj-working-fo – Parul Chauhan Dec 21 '17 at 07:00

3 Answers3

41

You have to create your own URLStreamHandler so that you can set URLConnection parameters like connection timeout and read timeout.

SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
URL endpoint =
  new URL(new URL("http://yourserver.yourdomain.com/"),
          "/path/to/webservice",
          new URLStreamHandler() {
            @Override
            protected URLConnection openConnection(URL url) throws IOException {
              URL target = new URL(url.toString());
              URLConnection connection = target.openConnection();
              // Connection settings
              connection.setConnectTimeout(10000); // 10 sec
              connection.setReadTimeout(60000); // 1 min
              return(connection);
            }
          });

SOAPMessage result = connection.call(soapMessage, endpoint);

I have removed some try/catch for clarity.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • Are you converting the URL passed to openConnection to a String and back to prevent target.openConnection from using the URLStreamHandler being defined? – Samuel Edwin Ward Mar 16 '12 at 20:02
  • That is a good point. I have not tested myself, but I think you guessed right: infinite recursion is closed ;) To be honest, I get that code from here: http://stackoverflow.com/questions/2148915/how-do-i-set-the-timeout-for-a-jax-ws-webservice-client – Yves Martin Mar 16 '12 at 21:38
  • That's funny, I think I saw that question but didn't look at the answers because it's a different problem (which I don't think that answer really addresses). – Samuel Edwin Ward Mar 16 '12 at 23:54
  • 1
    You're right. There is often a mistake between old-school SOAP API (your question) and new JAX-WS annotation based API (Zaki's answer here) – Yves Martin Mar 17 '12 at 07:21
  • @YvesMartin Please take some time out for the question below. I'm trying to set connect and read timeout which works fine for my windows OS however it fails to work as expected on linux based system https://stackoverflow.com/questions/47861767/http-connect-timeout-and-read-timeout-for-urlstreamhandler-with-saaj-working-fo – Parul Chauhan Dec 21 '17 at 06:58
  • 2
    I'm pretty sure this does not work any more. Both timeouts are overwritten by `HttpSOAPConnection` (version 1.5.2) in the call method. – T3rm1 Jul 09 '21 at 13:33
4
import com.sun.xml.internal.ws.client.BindingProviderProperties

public someResponse callWebService() {

    MyPort port = new Service().getPort();

    Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();

    requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, 10 * 1000); //10 secs

    requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, 1 * 60 * 1000); //1 min

    return port.someWebMethod();

}
Zaki
  • 6,997
  • 6
  • 37
  • 53
3

For the saaj implementation (version 1.5.2), it is possible to set the Java system properties

saaj.connect.timeout

and

saaj.read.timeout

Value is the timeout in milliseconds.

sleske
  • 81,358
  • 34
  • 189
  • 227
T3rm1
  • 2,299
  • 5
  • 34
  • 51