If you are using Spring for web services, there is a high probability that you have one of your classes extending WebServiceGatewaySupport class provided by Spring. This class has a method getWebServiceTemplate() that returns a WebServiceTemplate class on which you can invoke your requests to send and receive http requests. Typically, your code would look like:
public class RequestSender extends WebServiceGatewaySupport {
...
...
public void send(SomeWebServiceRequest request) {
SomeWebServiceResponse response = getWebServiceTemplate().marshalSendAndReceive(request);
}
...
...
}
Now, what if the server takes too long to respond? In that case, you shall receive a SocketTimeoutException. There is a way, though not direct, to set timeout using WebServiceTemplate so that your request does not timeout due to slower server response. Here is how you can do it ALL WITHIN SPRING CONTEXT. All you need is commons-httpclient. Assuming you are using maven, first you need to include a dependency on commons-httpclient as shown below:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
Including dependency above gives you access to HttpClient() class that we will use to set timeout. Once we have HttpClient with timeout set we shall inject this onto CommonsHttpMessageSender. It is this message sender that we are then going to inject onto WebServiceTemplate. Everything done via spring context config shown below:
...
...
<!-- Here is a relevant section of Spring Context -->
<bean id="reqSender" class="mypackage.RequestSender">
<property name="messageFactory">
<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
</property>
<property name="messageSenders">
<list>
<ref bean="httpSender" />
</list>
</property>
<property name="marshaller" ref="myMarshaller" />
<property name="unmarshaller" ref="myMarshaller" />
<property name="defaultUri" value="http://webservice-url/deployed/at/some/server" />
</bean>
<bean id="httpParams" class="org.apache.commons.httpclient.params.HttpClientParams">
<!-- Timeout in milliseconds: in this case 2 minutes -->
<property name="soTimeout" value="120000" />
</bean>
<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
<property name="params" ref="httpParams" />
</bean>
<bean id="httpSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
<constructor-arg>
<ref bean="httpClient"/>
</constructor-arg>
</bean>
<bean id="myMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
<property name="contextPath" value="path_to_directory_with_jaxb_xml_generated_classes"/>
</bean>
...
...
Well, hope that saves you hours of frustration trying to figure out how to set timeout in order to handle slow server response.
~srs