Sunday, November 23, 2008

Consuming web services with Spring

Consuming web services with Spring framework is amazingly easy. It avoids the need of creating client side stubs during compile time and does the same at run time. A typical web service client can be configured as shown below-

<bean id="myWebService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
    <property name="serviceInterface" value="pkg.MyService"/>
    <property name="wsdlDocumentUrl" value="http://localhost:8080/testws/myService?wsdl"/>
    <property name="namespaceUri" value="http://com.pkg/"/>
    <property name="serviceName" value="MyService"/>
    <property name="portName" value="MyServicePort"/>
Where serviceInterface is the business interface that clients will use for invoking service methods. wsdlDocumentUrl is the URL for the published WSDL file. Spring will download WSDL from the given URL and generate the client side stubs when it creates the bean usually during application start up. namespaceUri corresponds to the targetNamespace in the .wsdl file. serviceName corresponds to the service name in the .wsdl file. portName corresponds to the port name in the .wsdl file.

Now accessing web service pretty easy, just get the bean from Spring context and use that to invoke methods-
MyService myService = springContext.getBean("myWebService");
myService.someMethod(. . .);
One downside of this approach is that the web service must be up running when consumer application is being deployed. To avoid this problem one can use lazy-init="true" to lazily initialize the beans when they are first requested but all this quickly becomes unmanageable when we have an array of SOA based applications. In such a scenario one have to strictly follow the order of application deployment else deployment might fail.