Spring WS 1.0 API doesn’t support timeout for web service invocations. This feature can be achieved by using Jakarta Commons HttpClient. SSL timeout requires moreover the use of Not Yet Commons SSL (in fact, this product is just only an extension of JSSE).
Below a sample class and a sample application context configuration.
import java.io.IOException; import java.io.File; // commons-httpclient import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; // not-yet-commons-ssl import org.apache.commons.ssl.HttpSecureProtocol; import org.apache.commons.ssl.KeyMaterial; import org.apache.commons.ssl.TrustMaterial; // spring ws import org.springframework.oxm.xmlbeans.XmlBeansMarshaller; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.client.core.WebServiceMessageCallback; import org.springframework.ws.client.core.WebServiceTemplate; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import org.springframework.ws.transport.http.CommonsHttpMessageSender; public class SpringWSClient extends WebServiceGatewaySupport { // Marshalling private XmlBeansMarshaller xmlBeansMarshaller; // Truststore private String pathToJksTrustStore; private String jksTrustStorePassword; // Keystore private String pathToJksKeyStore; private String jksKeyStorePassword; // Timeout private int timeOutMs; // SSL Port private static final int SSL_PORT = 443; // Default constructor public SpringWSClient(XmlBeansMarshaller xmlBeansMarshaller) { this.xmlBeansMarshaller = xmlBeansMarshaller; } // Do WS invocation public Object callWs(Object input) { // SSL connection? if (getWebServiceTemplate().getDefaultUri().toLowerCase().startsWith( "https")) { sslProtocolInit(); } // Marshalling stuff (XMLBeans) WebServiceTemplate wst = getWebServiceTemplate(); wst.setMarshaller(getXmlBeansMarshaller()); wst.setUnmarshaller(getXmlBeansMarshaller()); // Timeout (commons-httpclient) HttpClient client = new HttpClient(); client.getParams().setSoTimeout(new Integer(getTimeOutMs())); CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender( client); wst.setMessageSender(messageSender); // Invocation Object result = wst.marshalSendAndReceive(input, new WebServiceMessageCallback() { public void doWithMessage(WebServiceMessage message) throws IOException { // ... } }); return result; } // SSL protocol (not-yet-commons-ssl) protected void sslProtocolInit() { HttpSecureProtocol protocolSocketFactory; try { protocolSocketFactory = new HttpSecureProtocol(); File jksTrustStore = new File(pathToJksTrustStore); TrustMaterial trustMaterial = new TrustMaterial(jksTrustStore, jksTrustStorePassword.toCharArray()); protocolSocketFactory.addTrustMaterial(trustMaterial); // No host name verification protocolSocketFactory.setCheckHostname(false); File jksKeyStore = new File(pathToJksKeyStore); KeyMaterial key = new KeyMaterial(jksKeyStore, jksKeyStorePassword .toCharArray()); protocolSocketFactory.setKeyMaterial(key); // Timeout protocolSocketFactory.setConnectTimeout(getTimeOutMs()); // Register protocol Protocol protocol = new Protocol("https", (ProtocolSocketFactory) protocolSocketFactory, SSL_PORT); Protocol.registerProtocol("https", protocol); } catch (Exception e) { e.printStackTrace(); } } public XmlBeansMarshaller getXmlBeansMarshaller() { return xmlBeansMarshaller; } public void setXmlBeansMarshaller(XmlBeansMarshaller xmlBeansMarshaller) { this.xmlBeansMarshaller = xmlBeansMarshaller; } public int getTimeOutMs() { return timeOutMs; } public void setTimeOutMs(int timeOutMs) { this.timeOutMs = timeOutMs; } public String getPathToJksFile() { return pathToJksFile; } public void setPathToJksFile(String pathToJksFile) { this.pathToJksFile = pathToJksFile; } public String getJksPassword() { return jksPassword; } public void setJksPassword(String jksPassword) { this.jksPassword = jksPassword; } }
simple and clean illustration. thanks a lot. will give it a try today.