Monday, August 3, 2009

Spring Web Service - Writing client

Now let us write dummy client to test the web service that we wrote earlier. Let us follow these steps -

1. Use the WSDL (http://localhost:8080/test/user.wsdl) and create the client classes. We can use XJC to create the classes. This is sample build.xml. Use "ant generate"

<?xml version="1.0"?>
<project name="spring-ws-user-ws-server" basedir="." default="default">
<path id="classpath">
<fileset dir="C:\jaxb-ri-20090708\lib">
<include name="**/*.jar"/>
</fileset>
</path>


<target name="generate">

<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask" classpathref="classpath" />

<xjc destdir="./gen" schema="http://localhost:8080/test/user.wsdl" package="com.test">
<arg value="-wsdl" />
</xjc>

</target>

</project>

2. Let us now define the marshaller / unmarshaller that is to be used by the client. Here we will use Jaxb2Marshaller. This is applicationContext_client.xml that I would be using.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="messagFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean id="abstractClient" abstract="true">
<constructor-arg ref="messagFactory"/>
<property name="destinationProvider">
<bean class="org.springframework.ws.client.support.destination.Wsdl11DestinationProvider">
<property name="wsdl" value="http://localhost:8080/test/userService/user.wsdl"/>
</bean>
</property>
</bean>

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.test" />
</bean>

<bean id="userService" parent="abstractClient" class="test.client.UserService">
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
</bean>

</beans>

3. Now write the class UserService that makes web service calls.

package test.client;

import javax.xml.bind.JAXBElement;

import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;

import com.test.AuthenticateUser;
import com.test.GetUserProfile;
import com.test.ObjectFactory;
import com.test.UpdateUserProfile;
import com.test.UserProfile;

public class UserService extends WebServiceGatewaySupport {

private String serviceUrl = "http://localhost:8080/test/userService";
private ObjectFactory objectFactory = new ObjectFactory();

public UserService(WebServiceMessageFactory messageFactory) {
super(messageFactory);
}

@SuppressWarnings("unchecked")
public int authenticateUser(String loginId, String password) {
AuthenticateUser request = objectFactory.createAuthenticateUser();
request.setLoginId(loginId);
request.setPassword(password);

getWebServiceTemplate().setDefaultUri(serviceUrl);

return ((JAXBElement<Integer>) getWebServiceTemplate()
.marshalSendAndReceive(request)).getValue();
}

@SuppressWarnings("unchecked")
public int updateProfile(String loginId, UserProfile profile) {
UpdateUserProfile request = objectFactory.createUpdateUserProfile();
request.setLoginId(loginId);
request.setProfile(profile);

getWebServiceTemplate().setDefaultUri(serviceUrl);

return ((JAXBElement<Integer>) getWebServiceTemplate()
.marshalSendAndReceive(request)).getValue();
}

@SuppressWarnings("unchecked")
public UserProfile getUserProfile(String loginId) {
GetUserProfile request = objectFactory.createGetUserProfile();
request.setLoginId(loginId);

getWebServiceTemplate().setDefaultUri(serviceUrl);

return ((JAXBElement<UserProfile>) getWebServiceTemplate()
.marshalSendAndReceive(request)).getValue();
}


}

4. Finally write a test class to test all the webservice methods.

package test.client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.ObjectFactory;
import com.test.UserProfile;

public class TestClient {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext_client.xml");
UserService userService = (UserService) applicationContext.getBean("userService", UserService.class);

int authenticate = userService.authenticateUser("pranav", "123123");
System.out.println("--Authenticate User -- " + authenticate);

ObjectFactory objectFactory = new ObjectFactory();
UserProfile profile = objectFactory.createUserProfile();
profile.setLoginId("pranav");
profile.setEmailId("pranav@xxx.com");
profile.setFirstName("Pranav");
profile.setLastName("Varshney");
profile.setAddress("Hyderabad");

int updateProfile = userService.updateProfile("pranav", profile);
System.out.println("--Update User Profile -- " + updateProfile);

UserProfile userProfile = userService.getUserProfile("pranav");
System.out.println("-- Get user Profile -- " + userProfile.getAddress()
+ " " + userProfile.getLoginId());
}
}


Make sure to have applicationContext_client.xml in the classpath and run the above TestClient.

Next we will look into securing web services.

2 comments:

Krishna said...

Hi , I am in need of help urgently. I have created a client which uses the spring ws. I have created a service using axis2 and deployed it in tomcats axis2 webapps. When i tried to send a simple request I get the following exception.

[ERROR] Exception occurred while trying to invoke service method org.apache.axis2.AxisFault: namespace mismatch require http://xxxxx.xxxx.xxxx.xxxxx.xxxx found none
at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.jav
a:172)

I have masked the method name had have masked the url. Could you please tell me if this could be due to namespace not getting set in Spring WS client. If so how can it be set. I am desperate now.
I would be extremely happy if you could help me in this.

秋珏 said...

Hi
thanks for ur informations. it's the same method i use.
I wonder how u manage the exceptions. For example while ur web service don't reply with a well formed response or not with a http response

Thanks again