WebServiceTemplate and Timeout

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;
  }

}

    
    
    
    
    
    
    

Published by angelborroy

Understanding software.

2 thoughts on “WebServiceTemplate and Timeout

Leave a comment