About Xavier Padro

Xavier is a software developer working in a consulting firm based in Barcelona. He is specialized in web application development with experience in both frontend and backend. He is interested in everything related to Java and the Spring framework

Spring Integration – Configure web service client timeout

Introduction

With the support of Spring Integration, your application can invoke a web service by using an outbound web service gateway. The invocation is handled by this gateway, thus you just need to worry about building the request message and handling the response. However, with this approach it is not obvious how to configure additional options like setting timeouts or caching of operations. This article will show how to set a client timeout and integrate it with the gateway.

This article is divided in the following sections:

  1. Introduction.
  2. Web service invocation overview.
  3. Configuring a message sender.
  4. The sample application.
  5. Conclusion.
  • The source code can be found at github.

Web service invocation overview

The web service outbound gateway delegates the web service invocation to the Spring Web Services WebServiceTemplate. When a message arrives to the outbound gateway, this template uses a message sender in order to create a new connection. The diagram below shows an overview of the flow:

int-timeout-sequence

By default, the web service template sets an HttpUrlConnectionMessageSender as its message sender, which is a basic implementation without support for configuration options. This behavior though, can be overridden by setting a more advanced message sender with the capability of setting both read and connection timeouts.

We are going to configure the message sender in the next section.

Configuring a message sender

We are going to configure a message sender to the outbound gateway. This way, the gateway will set the template’s message sender with the one provided.

The implementation we are providing in the example is the HttpComponentsMessageSender class, also from the Spring Web Services project. This message sender allows us to define the following timeouts:

  • connectionTimeout: Sets the timeout until the connection is established.
  • readTimeout: Sets the socket timeout for the underlying HttpClient. This is the time required for the service to reply.

Configuration:

<bean id="messageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
    <property name="connectionTimeout" value="${timeout.connection}"/>
    <property name="readTimeout" value="${timeout.read}"/>
</bean>

The properties file contains the values, which are both set to two seconds:

timeout.connection=2000

timeout.read=2000

Once configured, we add it to the web service outbound gateway configuration:

<int-ws:outbound-gateway uri="http://localhost:8080/spring-ws-courses/courses" 
    marshaller="marshaller" unmarshaller="marshaller" 
    request-channel="requestChannel" message-sender="messageSender"/>

To use this message sender, you will need to add the following dependency:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.3</version>
</dependency>

And that’s it; the next section will show the sample application to see how it works.

The sample application

The flow is simple; it consists in an application that sends a request to a web service and receives a response. The web service source code can be found at github.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-ws="http://www.springframework.org/schema/integration/ws"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
        http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
    
    <context:component-scan base-package="xpadro.spring.integration.ws"/>
    <context:property-placeholder location="classpath:props/service.properties"/>
    
    <!-- System entry -->
    <int:gateway id="systemEntry" default-request-channel="requestChannel" 
        service-interface="xpadro.spring.integration.ws.gateway.CourseService"/>
    
    <!-- Web service invocation -->
    <int-ws:outbound-gateway uri="http://localhost:8080/spring-ws-courses/courses" 
            marshaller="marshaller" unmarshaller="marshaller" 
            request-channel="requestChannel" message-sender="messageSender"/>
    
    <oxm:jaxb2-marshaller id="marshaller" contextPath="xpadro.spring.integration.ws.types" />
    
    <bean id="messageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
        <property name="connectionTimeout" value="${timeout.connection}"/>
        <property name="readTimeout" value="${timeout.read}"/>
    </bean>

</beans>

The gateway contains the method through which we will enter the messaging system:

public interface CourseService {
    
    @Gateway
    GetCourseResponse getCourse(GetCourseRequest request);
}

Finally, the test:

@ContextConfiguration(locations = {"/xpadro/spring/integration/ws/config/int-course-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class TestIntegrationApp {
    
    @Autowired
    private CourseService service;
    
    @Test
    public void invokeNormalOperation() {
        GetCourseRequest request = new GetCourseRequest();
        request.setCourseId("BC-45");
        
        GetCourseResponse response = service.getCourse(request);
        assertNotNull(response);
        assertEquals("Introduction to Java", response.getName());
    }
    
    @Test
    public void invokeTimeoutOperation() {
        try {
            GetCourseRequest request = new GetCourseRequest();
            request.setCourseId("DF-21");
            
            GetCourseResponse response = service.getCourse(request);
            assertNull(response);
        } catch (WebServiceIOException e) {
            assertTrue(e.getCause() instanceof SocketTimeoutException);
        }
    }
}

Conclusion

We have learnt how to set additional options to the web service outbound gateway in order to establish a timeout. In the next post, I will explain how to cache this invocation.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


9 + five =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books