Sie sind auf Seite 1von 21

Asif Akram; a.akram@dl.ac.

uk 1

Converting HelloWorld Web Service into WSRF based HelloWorld


Version: 1.2 Date 10/03/06

Web Services are stateless, they can’t differentiate different service calls from same client or different service
calls from different clients. This is understandable as most of Web Services using SOAP on http, which is
traditionally stateless. It is not necessary to use to http protocol for Web Services at least what the specifications
says but nearly all web services are based on http, the reason is to accommodate our existing knowledge of J2EE
or .Net. Using Java Servlet, Java Server Pages or Active Server Pages to make stateless Web Services, statefull
Web Services is not a rocket science, developers can extend web services in all possible ways by using proven
techniques of session handling to make them statefull but this kills the main purpose of Web Services, platform
and programming independency. Unique things in Web Services are Standards and in these already recognised
standards there is no place for home grown solutions; at least we should give try to standards rather than re-
inventing the wheel. Web Service Resource Frame Work WSRF is one of the standards, which extends stateless
Web Services using existing Web Service extensions such as WS-Addressing, WS-Notification, WS-Policy and
WS-Security. You don’t need to know all of them, you are free to use only those standards which meet your
requirements and if you know none of them then this series of tutorials will attempt to clear the usefulness of
them.

This first tutorial is about converting stateless Web Service into WSRF. Following the conventions we start with
HelloWorld example. This tutorial assumes that reader has enough knowledge of Web Services, Java
Programming and XML. These tutorials are based on Globus Toolkit 4, WS core component, which itself is
tightly coupled with Axis, so knowledge of Web Service in general and Axis Web Service in particular is
essential. If you are new to Web Services or Axis Web Services than there are enough tutorials available online
and many books are available on this topic. I will not spend time in covering Web Services in fact I will refer to
different web sites for better understanding.

• Web Services:
 http://www.phptr.com/content/images/0131428985/samplechapter/0131428985_ch03.pdf
 http://today.java.net/today/2003/11/05/ch4SOAP.pdf

• Axis Web Services:


 http://ws.apache.org/axis/java/user-guide.html
 http://www.sourcebeat.com/docs/Apache%20Axis%20Live/Rev_5/Apache%20Axis%20Live_SampleChapter.pdf
 http://www.j2ee-security.net/book/dnlds/Chapter11-WebService_Security.pdf

These tutorials have borrowed ideas from the following Globus and WSRF tutorials.
 http://gdp.globus.org/gt4-tutorial/
 https://www6.software.ibm.com/developerworks/education/gr-wsrf1/gr-wsrf1-a4.pdf
 https://www6.software.ibm.com/developerworks/education/gr-wsrf2/gr-wsrf2-a4.pdf
 https://www6.software.ibm.com/developerworks/education/gr-wsrf3/gr-wsrf3-a4.pdf
 https://www6.software.ibm.com/developerworks/education/gr-wsrf4/gr-wsrf4-a4.pdf

WS-Notification: This tutorial is not Globus Toolkit based but it is very helpful to understand WS-Notification
and to write your own WSRF implementation, the ideas represented here can be extended to any WS
sepecifications

 http://www-128.ibm.com/developerworks/grid/library/gr-ws-not/

If you find following tutorials helpful then credit goes to writers of above mentioned tutorials and if my tutorials
haven’t addressed your requirements then it was due to my limited knowledge.

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 2

Simple HelloWorld Web Service


We start understanding WSRF by creating very simple Web Service which echoes “Hello ….!”, …. are replaced
by the name passed to echo method. This Web Service is very simple java class called HelloWorld.java in the
package uk.ac.dl.ws.service.

package uk.ac.dl.ws.service;

public class HelloWorld {

public String echo(String name){


return "Hello " + name + " !";
}

This Web Service is self explanatory and assuming that Tomcat is running on local machine with Axis i.e. SOAP
Engine, we have to deploy this Web Service. To deploy Web Service through Axis needs deployment descriptor
which is simply xml file with extension wsdd; wsdd stands for Web Service Deployment Descriptor. Deployment
descriptor provides all information to Axis engine and can be quite complicated. For simple Web Services such as
our Web Service deployment descriptor is very simple.

?xml version="1.0" encoding="UTF-8"?>


<deployment name="defaultClientConfig"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler"
xmlns="http://xml.apache.org/axis/wsdd/">

<service name="HelloWorldService" type="" regenerateElement="true"


provider="java:RPC" style="rpc" use="encoded">
<parameter name="scope" value="Request" regenerateElement="false"/>
<parameter name="className"
value="uk.ac.dl.ws.service.HelloWorld" regenerateElement="false"/>
<parameter name="allowedMethods" value="*" regenerateElement="false"/>
</service>

</deployment>

After deploying our Web Service axis will use its own build in tool java2WSDL to generate WSDL file, which
explains how to access the Web Service and where it can be accessed. The WSDL file generated is below:
(Note: WSDL below is using RPC/Encoded Web Service which is not recommended way. Generating Document
/Literal or even Wrapped Document is just matter of different parameters for Java2WSDL)
I will soon upload the article related to WSDL and Web Services styles which will clear everything.

<?xml version="1.0" encoding="UTF-8"?>


<wsdl:definitions targetNamespace="http://service.ws.dl.ac.uk"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://service.ws.dl.ac.uk"
xmlns:intf="http://service.ws.dl.ac.uk"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 3

xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<wsdl:message name="echoRequest">
<wsdl:part name="name" type="xsd:string"/>
</wsdl:message>

<wsdl:message name="echoResponse">
<wsdl:part name="echoReturn" type="xsd:string"/>
</wsdl:message>

<wsdl:portType name="HelloWorld">
<wsdl:operation name="echo" parameterOrder="name">
<wsdl:input message="impl:echoRequest" name="echoRequest"/>
<wsdl:output message="impl:echoResponse" name="echoResponse"/>
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld">


<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="echo">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="echoRequest">
<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://service.ws.dl.ac.uk" use="encoded"/>
</wsdl:input>
<wsdl:output name="echoResponse">
<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://service.ws.dl.ac.uk" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="HelloWorldService">
<wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld">
<wsdlsoap:address location="http://localhost:8080/HelloWS130606/services/HelloWorld"/>
</wsdl:port>
</wsdl:service>

</wsdl:definitions>

This WSDL for our Web Service is very simple and needs no explanation but if you are new to WSDL or you
have only used different tools to generate WSDL rather than working with WSDL directly than better to have
look on the following link:

 http://www.oreilly.com/catalog/webservess/chapter/ch06.html

This link is from book Web Services Essentials, Distributed Applications with XML-RPC, SOAP, UDDI &
WSDL by Ethan Cerami.

WSDL for WSRF HelloWorld

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 4

To convert this simple Web Service from stateless to statefull we have to make few changes. Changes will start
from WSDL file and then changing the implementation of our HelloWorld.java class. Before making any changes
it is important to understand that how we will store the state of our Web Service. We need one variable called
“name” which will store the value passed to the echo method of our Web Service. This variable is Resource
Property of our Web Service, this concept is very clearly and in detail explained by Borja Sotomayor in “The
Globus Toolkit 4 Programmer’s Tutorial” under the section Getting Started. Remember your WSRF Web Service
can have many Resource Properties and all of them are placed in ResourcePropertySet for later retrieval,
modification and deletion. It is always nice to follow good naming conventions which are self explanatory, data
type which will encapsulate all Resources of our WSRF Web Services will ends with “ResourcePropertiesSet” to
indicate that it is ResourcePropertySet, all individual resources will ends with RP (Resource Property) to keep
things clear and simple. Let starts with our WSDL file, our final WSDL file for our Web Service will be
something similar to the WSDL file shown below. I have used the word final WSDL file which is too some extent
wrong, this WSDL file is not complete and Globus WSRF Implementation will add “binding” and “service”
information to this WSDL file but it is final from developers point of view as later he has nothing more to do with
this file. This WSDL is bit different from above WSDL as WSRF used Document Literal style Web Services.

<definitions name="HelloWorld"
targetNamespace="http://tutorial1.wsrf.dl.ac.uk/helloworld"
xmlns:tns="http://tutorial1.wsrf.dl.ac.uk/helloworld"
xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
xmlns:wsrlw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/WSDLPreprocessor"
xmlns:gtwsdl1="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.wsdl"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"
xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/">

<import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-BaseFaults-1.2-draft-01.wsdl"
location="../wsrf/faults/WS-BaseFaults.wsdl"/>

<!-- Required for Life Time Management of Resource Property can be removed without any problem -->
<import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
location="../wsrf/lifetime/WS-ResourceLifetime.wsdl"/>

<!-- Required for Resource Properties and should be available -->


<import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
location="../wsrf/properties/WS-ResourceProperties.wsdl"/>

<!-- Required for Notification can be removed without any problem -->
<import namespace="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"
location="../wsrf/notification/WS-BaseN.wsdl"/>

<!-- Required for ServiceGroup can be removed without any problem -->
<import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.wsdl"
location="../wsrf/servicegroup/WS-ServiceGroup.wsdl"/>

<types>
<schema
targetNamespace="http://tutorial1.wsrf.dl.ac.uk/helloworld"
xmlns:tns="http://tutorial1.wsrf.dl.ac.uk/helloworld"
xmlns="http://www.w3.org/2001/XMLSchema"

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 5

xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/ws/2004/03/addressing"
schemaLocation="../ws/addressing/WS-Addressing.xsd"/>

<!-- Required for ServiceGroup can be removed without any problem -->
<import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ServiceGroup-1.2-draft-01.xsd"
schemaLocation="../wsrf/servicegroup/WS-ServiceGroup.xsd"/>

<element name="name" type="xsd:string"/>

<element name="getNameRPRequest" >


<complexType/>
</element>
<element name="getNameRPResponse" type="xsd:string"/>

<element name="HelloWorldResourcePropertiesSet">
<complexType>
<sequence>
<element ref="tns:name"/>
</sequence>
</complexType>
</element>

<element name="echoRequest" type="xsd:string" />


<element name="echoResponse" type="xsd:string" />

</schema>
</types>

<message name="EchoRequest">
<part name="EchoRequest" element="tns:echoRequest" />
</message>
<message name="EchoResponse">
<part name="EchoResponse" element="tns:echoResponse" />
</message>

<message name="GetNameRPRequest">
<part name="GetNameRPRequest" element="tns: getNameRPRequest " />
</message>
<message name="GetNameRPResponse">
<part name="GetNameRPResponse" element="tns:getNameRPResponse" />
</message>

<portType name="HelloWorldPortType"
wsrp:ResourceProperties="HelloWorldResourcePropertiesSet">

<operation name="GetResourceProperty">
<input name="GetResourcePropertyRequest"
message="wsrpw:GetResourcePropertyRequest"
wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties/GetResourceProperty"/>
<output name="GetResourcePropertyResponse"
message="wsrpw:GetResourcePropertyResponse"

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 6

wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties/GetResourcePropertyResponse"/>
<fault name="InvalidResourcePropertyQNameFault"
message="wsrpw:InvalidResourcePropertyQNameFault"/>
<fault name="ResourceUnknownFault" message="wsrpw:ResourceUnknownFault"/>
</operation>

<!-- name in input and output is optional-->


<operation name="echo">
<input name="EchoRequest" message="tns:EchoRequest" />
<output name="EchoResponse" message="tns:EchoResponse" />
</operation>

<operation name="getNameRP">
<input name="GetNameRPRequest" message="tns:GetNameRPRequest" />
<output name="GetNameRPResponse" message="tns:GetNameRPResponse" />
</operation>

</portType>
</definitions>

This 2 page long WSDL file, which is still incomplete, is bit scary but in fact everything added in this file is very
logical and has its own significance. Immediately after the starting tag <definitions> there are 5 import statement
which are importing different WSDL files. We don’t need to import all these WSDL files for such a simple basic
example but for ease and convenience I have imported all of them and put comments when they are required, in
the following section I will discuss in detail the significance of each WSDL file and when it should be imported.
In the schema element of types we are once again importing 2 files but this time they are not WSDL files in fact
they are XMLSchema for different data types used in different WSDL files already imported. Thus in total, we
have imported 7 different files. These files are available on internet and also come with Globus WS Core
implementation; if you are interested to check these files than they are available in directory
“GTInstall\share\schema\wsrf” (GTInstall is directory where you have installed Globus Toolkit).

There are few changes in the WSDL file and we will discuss all these changes one by one:
1. Adding variable called “name” to store the value passed to echo (String name) method. Variable “name”
and parameter “name” passed to echo method can be called anything and there is no need to have them
same.
 <element name="name" type="xsd:string"/>
2. Two data types added to WSDL file related to the one additional method which will be added later. These
two complex data types are the following:
 <element name="getNameRPRequest" > <complexType/> </element>
 <element name="getNameRPResponse" type="xsd:string"/>
3. Data Type “getNameRPRequest” seems to be bit odd; in reality it is empty, equivalent to void, or method
call without any parameter. This is requirement of Document Literal style Web Services that each
complex or simple type should be wrapped in elements.
4. Data Type “getNameRPResponse” is of type String as our method will return String, it can be of any built
in or composite data type as required by business logic.
5. The most important part is to add data Type “HelloWorldResourcePropertiesSet”. This element wraps all
variables (each WSRF related Resource Properties) in our service to be implemented as Resource
Properties. Web Service can have many variables and few of them can be only utility variable required for
the proper functionality of the Web Service and there is no need to store the state of these variables. Only
those variables which have to do with the state of Web Service are wrapped in the composite variable,
which is recommended to have ResourcePropertiesSet at the end of its name. Only convention, nothing to

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 7

do with actual implementation. In our case there is only one variable “name” which should be wrapped as
resource property, therefore “HelloWorldResourcePropertiesSet” refers to variable “name”.
6. We have added new operation called “getNameRP” at the end of the WSDL file in the <portType>
element. This is custom element which will return the current value of variable “name”. This operation
takes no parameter that’s why “getNameRPRequest” is empty and returns String as indicated by
"getNameRPResponse".
7. Related to the operation “getNameRP” we have corresponding messages i.e. GetNameRPRequest,
GetNameRPResponse, it is important to mention operation works on messages and message wraps
different elements defined in types.
8. The most important change which is must and to some extent the same for all WSRF implementations is
to add operation "GetResourceProperty", the messages involved in this operation are already defined in
the “wsrf-WS-ResourceProperties-1.2-draft-01.wsdl” so we don’t have to do anything special and even
the implementation of this operation is very simple, we have to provide implementation to this operation.
9. We have related “GetResourceProperty" operation with our custom resource property and in this Web
Service it is "HelloWorldResourcePropertiesSet". These two are linked in the element “<portType>” with
the attribute “wsrp:ResourceProperties”.
<portType name="HelloWorldPortType wsrp:ResourceProperties="HelloWorldResourceProperties">
For its inner details refer to Borja Sotomayor’s tutorial section WSRF and Globus-specific features of
WSDL.
10. The last few changes are to delete the details of “binding” and “service” from existing WSDL file.

These are the all changes we need to make to our WSDL files. My preferred style is to write Web Service and
generate WSDL file using jave2WSDL and then modify the WSDL file to make it WSRF WSDL file. I am
currently working on tool to create WSRF WSDL file from existing WSDL file based on user input for my own
work. When I will finish it depends on how much desperate I am from any such tool, and how many other
programmers are interested in such a tool. If you are interested in any such tool and feel that it will be helpful for
whole community then do mail me. It will speed up the process.

HelloWorld WSRF Implementation


Now we have to change our HelloWorld.java class. Initially we are going to change our implementation without
any additional java class, which is not recommended way and kills the purpose of OO, but for convenience we
will follow this path, later we will separate them in different classes as done in the “StickyNote” example which
comes with Globus Toolkit or can be downloaded separately.

1. First of all we have to import couple of classes which are part of Globus WSRF implementation and few
classes which don’t exist. Classes which don’t exist ..? Yes! these are classed generated by Globus WSRF
implementation when we will parse our WSDL file, compile HelloWorld.java and deploy it to the server.
These additional classes are very similar to stubs and skeletons created by Axis Engine and in fact are
tightly coupled to Axis.
 import java.rmi.RemoteException;
 import javax.xml.namespace.QName;
 import org.globus.wsrf.Resource;
 import org.globus.wsrf.ResourceProperties;
 import org.globus.wsrf.ResourceProperty;
 import org.globus.wsrf.ResourcePropertySet;
 import org.globus.wsrf.impl.ReflectionResourceProperty;
 import org.globus.wsrf.impl.SimpleResourcePropertySet;
 import uk.ac.dl.wsrf.tutorial1.helloworld.*;

Be sure about the last import statement, these are classes in the new package which matches the target
namespace mentioned in our WSDL file.
targetNamespace="http://tutorial1.wsrf.dl.ac.uk/helloworld"

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 8

We can change this mapping from this “targetNamespace” to any required package by providing a simple
text file called NStoPkg.properties, which, I have avoided in this simple tutorial.

Package uk.ac.dl.wsrf.tutorial.helloworld.* has few classes which are used by client and service both, If
you remember when we were changing the WSDL file, I talked about wrapper to represent void and
empty parameter to method call. Our both methods echo() and getNameRP() return String but
getNameRP() doesn’t take any parameter and this is wrapped in the empty dataType
"getNameRPRequest". Stub will be created representing this data type and the name of stub generated is
GetNameRPRequest.java. It is important to understand as you have to import the related classes which are
still not available and you should know the location and name of these classes by analysing the modified
WSDL file at the time when Web Service is implemented.
2. HelloWorld.java implements Resource, ResourceProperties, which is requirement.
public class HelloWorld implements Resource, ResourceProperties { …}
3. We need one set which will manage all related resource properties of our Web Service. In this example we
have only one resource property but still we need ResourcePropertySet and we need it for all of our
WSRF Web Services.
/* Resource Property set */
private ResourcePropertySet propSet;
4. Now we have to declare the variable “name” of type String which represents Resource Property of our
Web Service. It is not necessary to have this name as it is in the WSDL file.
5. In the constructor of our Web Service we will initialize the ResourcePropertySet and our Resource
Property “name”.

public HelloWorld() throws RemoteException {


/* Create RP set */
this.propSet = new SimpleResourcePropertySet(
new QName("http://tutorial1.wsrf.dl.ac.uk/helloworld", "HelloWorldResourcePropertiesSet"));

/* Initialize the RP's */


try {
ResourceProperty nameRP = new ReflectionResourceProperty(
new QName("http://tutorial1.wsrf.dl.ac.uk/helloworld", "name"), "name", this);
this.propSet.add(nameRP);
setName("Asif"); // this is set method for private variable name
}
catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}

Let see what is happening in the constructor. This is the ugliest way to implement WSRF, but I want to
keep my words of doing everything in single java class. I am sure it will hurt OO purist very badly, but
trust me it is also hurting me a lot, but my main purpose is to clear the concept of WSRF as easily as
possible, soon we will start working on WSRF with OO techniques, best of both world.
We have initialized the “propSet” as object of SimpleResourcePropertySet, you may have figured out that
ResourcePropertySet is interface and SimpleResourcePropertySet is concrete implementation of
ResourcePropertySet. Constructor of SimpleResourcePropertySet takes QName i.e. the qualified name of
our resource property as declared in the WSDL file. Similarly ResourceProperty is an interface and
ReflectionResourceProperty is one of its implementation used to declare and create variable nameRP
(name Resource Property). ReflectionResourceProperty has three different constructors and the
constructor used in the above example is: ReflectionResourceProperty(QName name,
String propertyName, Object obj), QName should match the qualified name in the WSDL and

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 9

String propertyName is the name of variable in our implementation. It can be called anything like
myName.
Now we have to add this newly created ResourceProperty into our ResourcePropertySet,
this.propSet.add(nameRP) and then assign initial value by calling utility set method for private variable
name.
6. If you remember we have three operations in our WSDL file two declared by us for custom business logic
and one from imported WSDL file. It means along with different get/set methods for our different private
variables we have to provide public implementation of these three operations, which is trivial task. Below
is the implementation of our all three operations:

public String echo(String name) {


setName(name); // this is important.
return "Hello " + name + " !";
}

public String getNameRP(uk.ac.dl.wsrf.tutorial1.helloworld .GetNameRP params) throws RemoteException {


return name;
}

/* Required by interface ResourceProperties */


public ResourcePropertySet getResourcePropertySet() {
return this.propSet;
}

All three methods are self-explanatory, the most important thing is to implement getResourcePropertySet()
which is declared in the interface ResourceProperties implemented by our Web Service.

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 10

Complete implementation of HelloWorld.java is shown below:

import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import org.globus.wsrf.Resource;
import org.globus.wsrf.ResourceProperties;
import org.globus.wsrf.ResourceProperty;
import org.globus.wsrf.ResourcePropertySet;
import org.globus.wsrf.impl.ReflectionResourceProperty;
import org.globus.wsrf.impl.SimpleResourcePropertySet;
import uk.ac.dl.wsrf.tutorial1.helloworld.*;

public class HelloWorld implements Resource, ResourceProperties {


/* Resource Property set */
private ResourcePropertySet propSet;

/* Resource properties */
private String name;

public HelloWorld() throws RemoteException {


/* Create RP set */
this.propSet = new SimpleResourcePropertySet(
new QName("http://tutorial.wsrf.dl.ac.uk/helloworld", "HelloWorldResourceProperties"));
/* Initialize the RP's */
try {
ResourceProperty nameRP = new ReflectionResourceProperty(
new QName("http://tutorial.wsrf.dl.ac.uk/helloworld", "name"), "name", this);
this.propSet.add(nameRP);
setName("Asif"); // this is set method for private variable name
}
catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public String echo(String name) {


setName(name);
return "Hello " + name + " !";
}

public String getNameRP(uk.ac.dl.wsrf.tutorial1.helloworld .GetNameRP params) throws RemoteException {


return name;
}
/* Required by interface ResourceProperties */

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 11

public ResourcePropertySet getResourcePropertySet() {


return this.propSet;
}
}

WSDD for HelloWorld WSRF


Have we finished our first WSRF Web Service? Not yet … Don’t forget we need Axis Engine dependent
Deployment Descriptor to deploy our Web Service. There are not too many changes in the initial WSDD and the
modified WSDD.

<deployment name="defaultServerConfig" xmlns="http://xml.apache.org/axis/wsdd/"


xmlns:aggr="http://mds.globus.org/aggregator/types"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<service name="HelloWorldService" provider="Handler" use="literal" style="document">
<parameter name="providers" value="GetRPProvider"/>
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/>
<parameter name="scope" value="Application"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="activateOnStartup" value="true"/>
<parameter name="className" value=" uk.ac.dl.ws.service.HelloWorld "/>
<wsdlFile>share/schema/tutorial/HelloWorld_service.wsdl</wsdlFile>
</service>
</deployment>

Important <wsdlFile>….</wsdlFile> stops Axis to replacing WS-Core generated WSDL with its own WSDL file
which is collection of problems uses its own encoding style which has interoperability problems
.
Main difference is that we are using Globus Toolkit provided handler. Handlers are java classes which are
involved in pre and post handling of request and response from Web Service. If you are new to idea of Handlers
in Axis then best to read the sample chapter “Custom Handlers in AXIS” from one of great Axis Web Service
book “AXIS: Next Generation Java SOAP“ by Romin Irani, S Jeelani Basha.

 http://archive.devx.com/java/wrox/7159_chap04.pdf

Second change is to make it clear that we are using default implementation of GetRPProvider, provided by
Globus implementation.
<parameter name="providers" value="GetRPProvider"/>

deploy-jndi for HelloWorld WSRF


The last thing we need is “deploy-jndi-config.xml”. This file is related to Tomcat Server and tells the server about
the services and the class which provides the detail of services. This file is very simple as we are using custom
implementation provided by Globus to wrap our WSRF Web Service. This may be bit confusing but it will be
clear in the later tutorials.

<jndiConfig xmlns="http://wsrf.globus.org/jndi/config">

<service name="HelloWorldService">
<resource name="home" type="org.globus.wsrf.impl.ServiceResourceHome">
<resourceParams>
<parameter>
<name>factory</name>
<value>org.globus.wsrf.jndi.BeanFactory</value>
WSRF Based Hello World Web Service
Asif Akram; a.akram@dl.ac.uk 12

</parameter>
</resourceParams>
</resource>
</service>

</jndiConfig>

If you are confused about role of this file then you can read about this on official web site of Tomcat Server.

WSRF HelloWorld Client


Last thing to do is to write Client to test our WSRF Web Service. Below is the complete code of Client.java
followed by discussion of important parts, notice that Client.java is in package “uk.ac.dl.ws.service.client” and
our service HelloWorld.java is in package “package uk.ac.dl.ws.service”. This is not the requirement of WSRF or
Globus implementation of WSRF, in fact it is restriction due to the Ant “build.xml” file which will be used later
to generate stubs, compile service and deploy to the container. You can change “build.xml” to adjust changes
made in your package structure. We have to put all java classes and additional files like WSDL and “deploy-jndi-
config.xml” in specific directories as required by Ant “build.xml”. Ant “build.xml” is so handy and useful that
following few restrictions is still worthy, as it hides all dirty work of setting class path, copying files from
different locations and above all making all imported files in our WSDL available to our WSDL file.

package uk.ac.dl.ws.service.client;

import org.apache.axis.message.MessageElement;
import org.apache.axis.message.Text;

import org.apache.axis.types.URI;

import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.CommandLine;

import org.oasis.wsrf.properties.WSResourcePropertiesServiceAddressingLocator;
import org.oasis.wsrf.properties.GetResourceProperty;
import org.oasis.wsrf.properties.GetResourcePropertyResponse;
import org.oasis.wsrf.properties.QueryResourceProperties_Element;
import org.oasis.wsrf.properties.QueryResourcePropertiesResponse;
import org.oasis.wsrf.properties.QueryResourceProperties_PortType;
import org.oasis.wsrf.properties.QueryExpressionType;

import org.globus.wsrf.WSRFConstants;
import org.globus.wsrf.client.BaseClient;
import org.globus.wsrf.utils.AnyHelper;
import org.globus.wsrf.utils.FaultHelper;

import javax.xml.namespace.QName;
import javax.xml.rpc.Stub;
import uk.ac.dl.wsrf.tutorial1.helloworld.service.*;
import uk.ac.dl.wsrf.tutoria1l.helloworld.*;

public class Client1 extends BaseClient {

final static WSResourcePropertiesServiceAddressingLocator locator =

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 13

new WSResourcePropertiesServiceAddressingLocator();

public static void main(String[] args) {


Client1 client = new Client1 ();

// first, parse the commandline


try {
CommandLine line = client.parse(args);
}
catch (ParseException e) {
System.err.println("Parsing failed: " + e.getMessage());
System.exit(1);
}
catch (Exception e) {
System.err.println("Error: " + e.getMessage());
System.exit(1);
}

try {

GetResourceProperty port = locator.getGetResourcePropertyPort(client.getEPR());


client.setOptions( (Stub) port);

GetResourcePropertyResponse response =
port.getResourceProperty(new QName("http://tutorial.wsrf.dl.ac.uk/helloworld", "name"));
System.out.println(AnyHelper.toSingleString(response));

uk.ac.dl.wsrf.tutorial1.helloworld.service.HelloWorldServiceAddressingLocator mylocator =
new uk.ac.dl.wsrf.tutorial1.helloworld.service.HelloWorldServiceAddressingLocator();

uk.ac.dl.wsrf.tutoria1l.helloworld.HelloWorldPortType myPort =
mylocator.getHelloWorldPortTypePort (client.getEPR());
String result = myPort.echo("Rob Allan");

response = port.getResourceProperty new QName("http://tutorial.wsrf.dl.ac.uk/helloworld", "name"));


System.out.println(AnyHelper.toSingleString(response));

}
catch (Exception e) {
if (client.isDebugMode()) {
FaultHelper.printStackTrace(e);
}
else {
System.err.println("Error: " + FaultHelper.getMessage(e));
}
}
}

Implementation once again starts with importing couple of Globus dependent java classes along with importing
few classes which are not yet available and will created by Ant build file. One of them is to locate the our Web

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 14

Service ”HelloWorldServiceAddressingLocator” which is in package “uk.ac.dl.wsrf.tutorial.helloworld.service”


and the “HelloWorldPortType” which is the interface with all three methods available in our main Web Service.
“HelloWorldPortType” is available in the package “import uk.ac.dl.wsrf.tutorial.helloworld”. Our client
implementation is using two different approaches to get hold of stub to communicate with Web Service i.e. first
we are using Globus provided class WSResourcePropertiesServiceAddressingLocator through which we obtain
generic stub GetResourceProperty, limitation of this approach is that we can only access one method which must
be implemented by the Web Service that’s is getResourceProperty() as shown in following code fragment;

WSResourcePropertiesServiceAddressingLocator locator= new


WSResourcePropertiesServiceAddressingLocator();
GetResourceProperty port = locator.getGetResourcePropertyPort(client.getEPR());
port.getResourceProperty(……….);

Second approach is to use HelloWorldServiceAddressingLocator to create custom stub HelloWorldPortType,


through this stub we have access to all operations exposed by WSDL as shown in following code fragment;

HelloWorldServiceAddressingLocator mylocator = new HelloWorldServiceAddressingLocator();


HelloWorldPortType myPort = mylocator.getHelloWorldPortTypePort (client.getEPR());
String result = myPort.echo("Rob Allan");

Now everything is available and we have to build the WSRF Web Service. For build purposes we will use build
tool “ANT” and the build.xml provided by the Globus. To make life easy to test web service we need last file
“post-deploy.xml“ which will create script to run the client, without setting class path, without worrying about the
generated stubs and location of compiled stubs. This xml file is generated when everything goes well, below are
the contents of file “post-deploy.xml”.

<project default="all" basedir=".">


<property environment="env"/>
<property file="build.properties"/>
<property file="${user.home}/build.properties"/>
<property name="env.GLOBUS_LOCATION" value="."/>
<property name="deploy.dir" location="${env.GLOBUS_LOCATION}"/>
<property name="abs.deploy.dir" location="${deploy.dir}"/>
<property name="build.launcher"
location="${abs.deploy.dir}/share/globus_wsrf_common/build-launcher.xml"/>

<target name="setup">
<ant antfile="${build.launcher}"
target="generateLauncher">
<property name="launcher-name" value="helloworld"/>
<property name="class.name" value="uk.ac.dl.ws.service.client.Client"/>
</ant>
</target>
</project>

This file is quite simple, and most of time remains same for most of clients. There are two adjustments to be made
for each client and location of those adjustments is shown in bold. Name of the generated script: <property
name="launcher-name" value="helloworld"/> and location and name of java client of WSRF Web Service. In
our case client is “Client1.java” in package “uk.ac.dl.ws.service.client”. Now we have to use Ant build file, but
that Ant file also needs few changes related to our Web Service. These changes are very small and are the last
step required to finish the whole implementation.

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 15

I have copied the complete build file and highlighted the changes:

<?xml version="1.0" encoding="UTF-8"?>


<!— project name is used to create the final jar and gar files -->
<project basedir="." default="all" name="globus_tutorial_helloworld">

<property environment="env"/>

<property file="build.properties"/>
<property file="${user.home}/build.properties"/>
<!— should be related to your Globus Server Installation not required if GLOBUS_LOCATION set
<property location="../install" name="env.GLOBUS_LOCATION"/>
-->
<property location="${env.GLOBUS_LOCATION}" name="deploy.dir"/>
<property name="base.name" value="tutorial_helloworld"/>
<property name="package.name" value="globus_${base.name}"/>
<property name="jar.name" value="${package.name}.jar"/>
<property name="gar.name" value="${package.name}.gar"/>
<property location="build" name="build.dir"/>
<property location="build/classes" name="build.dest"/>
<property location="build/lib" name="build.lib.dir"/>
<property location="build/stubs" name="stubs.dir"/>
<property location="build/stubs/src" name="stubs.src"/>
<property location="build/stubs/classes" name="stubs.dest"/>
<property name="stubs.jar.name" value="${package.name}_stubs.jar"/>
<property location="${deploy.dir}/share/globus_wsrf_common/build-packages.xml"
name="build.packages"/>
<property location="${deploy.dir}/share/globus_wsrf_tools/build-stubs.xml" name="build.stubs"/>
<property name="java.debug" value="on"/>

<property name="test-reports.dir" value="test-reports"/>


<property name="junit.haltonfailure" value="true"/>

<property location="${deploy.dir}/share/schema" name="schema.src"/>


<property location="${build.dir}/schema" name="schema.dest"/>

<property name="garjars.id" value="garjars"/>


<fileset dir="${build.lib.dir}" id="garjars"/>

<property name="garschema.id" value="garschema"/>


<fileset dir="${schema.dest}" id="garschema" includes="tutorial/*"/>

<property name="garetc.id" value="garetc"/>


<fileset dir="etc" id="garetc"/>

<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.dest}"/>
<mkdir dir="${build.lib.dir}"/>

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 16

<mkdir dir="${stubs.dir}"/>
<mkdir dir="${stubs.src}"/>
<mkdir dir="${stubs.dest}"/>

<mkdir dir="${schema.dest}"/>

<copy toDir="${schema.dest}">
<fileset dir="${schema.src}" casesensitive="yes">
<include name="wsrf/**/*"/>
<include name="ws/**/*"/>
</fileset>
</copy>
<copy toDir="${schema.dest}">
<fileset dir="schema/" casesensitive="yes">
<include name="tutorial/*"/>
</fileset>
</copy>

<available file="${stubs.dest}/org.globus.wsrf.mds.aggregator" property="stubs.present" type="dir"/>


</target>

<target name="bindings" depends="init">


<ant antfile="${build.stubs}" target="generateBinding">
<property name="source.binding.dir"
value="${schema.dest}/tutorial"/>
<property name="target.binding.dir"
value="${schema.dest}/tutorial"/>
<property name="binding.root" value="HelloWorld"/>
<property name="porttype.wsdl" value="helloworld_port_type.wsdl"/>
</ant>

</target>

<target name="stubs" unless="stubs.present" depends="bindings">


<ant antfile="${build.stubs}" target="generateStubs">
<property location="${schema.dest}/tutorial" name="source.stubs.dir"/>
<property name="wsdl.file" value="HelloWorld_service.wsdl"/>
<property location="${stubs.src}" name="target.stubs.dir"/>
</ant>
</target>

<target depends="stubs" name="compileStubs">


<delete dir="${stubs.src}/org/apache"/>
<javac debug="${java.debug}" destdir="${stubs.dest}" srcdir="${stubs.src}">
<include name="**/*.java"/>
<classpath>
<fileset dir="${deploy.dir}/lib">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 17

</target>

<target depends="compileStubs" name="compile">


<javac debug="${java.debug}" destdir="${build.dest}" srcdir="src">
<include name="**/*.java"/>
<classpath>
<pathelement location="${stubs.dest}"/>
<fileset dir="${deploy.dir}/lib">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>

<target depends="compileStubs" name="jarStubs">


<jar basedir="${stubs.dest}" destfile="${build.lib.dir}/${stubs.jar.name}"/>
</target>

<target depends="compile" name="jar">


<jar basedir="${build.dest}" destfile="${build.lib.dir}/${jar.name}"/>
</target>

<target depends="jar, jarStubs" name="dist">


<ant antfile="${build.packages}" target="makeGar">
<property name="gar.name" value="${build.lib.dir}/${gar.name}"/>
<reference refid="${garjars.id}"/>
<reference refid="${garschema.id}"/>
<reference refid="${garetc.id}"/>
</ant>
</target>

<target name="clean">
<delete dir="tmp"/>
<delete dir="${build.dir}"/>
<delete file="${gar.name}"/>
<delete dir="${test-reports.dir}"/>
</target>

<target depends="dist" name="deploy">


<ant antfile="${build.packages}" target="deployGar">
<property name="gar.name" value="${build.lib.dir}/${gar.name}"/>
<property name="gar.id" value="${package.name}"/>
<!-- <property name="noSchema" value="true"/> -->
</ant>
</target>

<target name="undeploy">
<ant antfile="${build.packages}" target="undeployGar">
<property name="gar.id" value="${package.name}"/>
</ant>
</target>

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 18

<target depends="deploy" name="all"/>

<target depends="compile" name="test">


<mkdir dir="${test-reports.dir}"/>
<junit fork="yes" haltonfailure="${junit.haltonfailure}" printsummary="yes" timeout="600000">
<classpath>
<pathelement location="${build.dest}"/>
<pathelement location="${deploy.dir}"/>
<pathelement location="${deploy.dir}/etc/wsrf-bundles.properties"/>
<fileset dir="${deploy.dir}/lib">
<include name="*.jar"/>
</fileset>
</classpath>
<formatter type="xml"/>
<batchtest todir="${test-reports.dir}">
<fileset dir="${build.dest}">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
</junit>
</target>
</project>

Important: Few important things about this the ant script. Project name is used to create the jar and gar files.
Value for property binding.root in target bindings
i.e. <property name="binding.root" value="HelloWorld"/>
is used as value for property wsdl.file in target stubs
i..e. <property name="wsdl.file" value="HelloWorld_service.wsdl"/>
with suffix “_service.wsdl”.

Now we have all required java files and configuration files, but before we can run Ant script we have to put them
at proper location where Ant build can locate them. HelloWorld140605/source is the main directory containing all
files under one umbrella:
1. Web Service implementation HelloWorld.java will be in the directory structure according to package
statement i.e. “HelloWorld140605\source\src\uk\ac\dl\ws\service” (1)
2. Client1.java will be the directory “HelloWorld140605\source\src\uk\ac\dl\ws\service\client” (2).
3. WSDL file “helloworld_port_type.wsdl” is located at “HelloWorld140605\source\schema\tutorial”
indicated by (3)
4. Source directory (4) contains “deploy-server.wsdd”, “deploy-jndi-config.xml” and “build.xml”.
5. File “post-deploy.xml”, which; is used for creating client script is in directory
“HelloWorld140605\source\etc” (5).
6. “build” directory will be created on successful stub generation and stores compiled classes and jar files
for the WSRF project

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 19

1
2

I am using Windows Operating System and have installed only WS-Core component of Globus Toolkit. You have
to set an environment variable called GLOBUS_LOCATION referencing the installation of Globus Toolkit. In
my case it is:
set GLOBUS_LOCATION= E:\GlobusWeek\gt-install
Open two Command Prompt one for starting Globus Tomcat Server and other for deploying Web Service and
testing client. In one Window go to directory “E:\GlobusWeek\gt-install” and run command,
bin\globus-start-container –nosec
which will start the container.
On second window go to directory E:\GlobusWeek\HelloWorld140605\source and run build file to create stubs,
compile all java files, and deploy Web Service.
ant clean
ant deploy
If everything goes fine then after 10 seconds you will see the final outcome similar to:
generateWindows:
[echo] Creating Windows launcher script helloworld
[copy] Copying 1 file to E:\GlobusWeek\gt-install\bin
[delete] Deleting: E:\GlobusWeek\HelloWorld140605\source\tmp\gar\etc\post-deploy.xml
[delete] Deleting directory E:\GlobusWeek\HelloWorld140605\source\tmp\gar
BUILD SUCCESSFUL
Total time: 8 seconds

If you remember in the file “post-deploy.xml” we have mentioned helloworld as name of script to be generated to
run the client, which is confirmed by the final outcome of the Ant build file. Now it is time to run the client:
%GLOBUS_LOCATION%\bin\helloworld -s http://localhost:8080/wsrf/services/HelloWorldService
<ns1:name xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld">Asif</ns1:name>
<ns1:name xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld">Rob Allan</ns1:name>

“Asif “ is the initial value assigned to our variable “name” and “Rob Allan” is the value assigned to variable “name” from
“Client1.java”. If you will run the script again then the out come will be:
%GLOBUS_LOCATION%\bin\helloworld -s http://localhost:8080/wsrf/services/HelloWorldService
<ns1:name xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld"> Rob Allan </ns1:name>
<ns1:name xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld">Rob Allan</ns1:name>

When we are running the client script for second time, our name variable has already value “Rob Allan” and we
are assigning the same value again, due to which it has printed “Rob Allan” both times.

“helloworld” script is calling the service 3 times, and if you see the SOAP messages then there are 3 calls, twice
we are calling “getResourceProperty(..)” and once we are calling “echo()” method. Call to “echo()” method is
simple SOAP call, below is the SOAP request and SOAP response from “getResourceProperty(..)” and “echo()”
method. There is nothing too much complicated happening here. Most important thing to remember is that each
resource in WSRP has unique ID which along with the URL of Web Service is called End Point Reference. In this

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 20

simple example, for all clients there is only one copy of the resource. In other words clients are sharing the
resource but if multiple copies of the resource are possible then each copy will have unique ID which we will see
in the later examples. When clients make a request, it sends its URL or location where Web Service can send the
response. “http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous” is special instruction to Web
Service indicating that there is no real endpoint available for this address and to keep the “http” connection open
and use the same connection to send the response, which means we can have synchronously or asynchronously
web services. Client sends the SOAP Request and SOAP Response can be sent to the URL provided, therefore
client doesn’t have to wait for the response, which is non-blocking call. Even the request can be sent to any other
URL provided by the client. Requester and Receiver can be different. More on this later, when, we will see the
WS-Addressing Specification in more detail. To understand the purpose and reason behind this new specification
WS-Addressing there is a tutorial by Doug Davis on IBM website.

 http://www-106.ibm.com/developerworks/library/ws-address.html

Below is the table showing SOAP Request and SOAP Response to both methods in tabular form. I have done
little editing to fit them in single table and two columns.

SOAP Request Soap Response


<soapenv:Envelope <soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"> xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<soapenv:Header>
<soapenv:Header> <wsa:MessageID soapenv:mustUnderstand="0">
uuid:88709a20-dcc1-11d9-b359-f53ae5575587
<wsa:MessageID soapenv:mustUnderstand="0"> </wsa:MessageID>
uuid:881ab1f0-dcc1-11d9-ae7c-b8ea2ebe6b67 <wsa:To soapenv:mustUnderstand="0">
</wsa:MessageID> http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous
<wsa:To soapenv:mustUnderstand="0"> </wsa:To>
http://localhost:8082/wsrf/services/HelloWorldService <wsa:Action soapenv:mustUnderstand="0">
</wsa:To> http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resource
<wsa:Action soapenv:mustUnderstand="0"> Properties/GetResourcePropertyResponse
http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS- </wsa:Action>
ResourceProperties/GetResourceProperty <wsa:From soapenv:mustUnderstand="0">
</wsa:Action> <wsa:Address>
<wsa:From soapenv:mustUnderstand="0"> http://localhost:8082/wsrf/services/HelloWorldService
<wsa:Address> </wsa:Address>
</wsa:From>
http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous <wsa:RelatesTo RelationshipType="wsa:Reply"
</wsa:Address> soapenv:mustUnderstand="0">
</wsa:From> uuid:881ab1f0-dcc1-11d9-ae7c-b8ea2ebe6b67</wsa:RelatesTo>
</soapenv:Header> </soapenv:Header>
<soapenv:Body> <soapenv:Body>
<GetResourceProperty <GetResourcePropertyResponse
xmlns="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resource xmlns="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-
Properties-1.2-draft-01.xsd" ResourceProperties-1.2-draft-01.xsd">
xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld"> <ns1:name
ns1:name xmlns:ns1="http://tutorial1.wsrf.dl.ac.uk/helloworld">
</GetResourceProperty> Asif
</ns1:name>
</soapenv:Body> </GetResourcePropertyResponse>
</soapenv:Body>
</soapenv:Envelope> </soapenv:Envelope>
<soapenv:Envelope <soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"> xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<soapenv:Header> <soapenv:Header>
<wsa:MessageID soapenv:mustUnderstand="0"> <wsa:MessageID soapenv:mustUnderstand="0">
uuid:88c65b40-dcc1-11d9-ae7c-b8ea2ebe6b67 uuid:88c8cc40-dcc1-11d9-b359-f53ae5575587
</wsa:MessageID> </wsa:MessageID>
<wsa:To soapenv:mustUnderstand="0"> <wsa:To soapenv:mustUnderstand="0">

WSRF Based Hello World Web Service


Asif Akram; a.akram@dl.ac.uk 21

http://localhost:8082/wsrf/services/HelloWorldService http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous
</wsa:To> </wsa:To>
<wsa:Action soapenv:mustUnderstand="0"> <wsa:Action soapenv:mustUnderstand="0">
http://tutorial1.wsrf.dl.ac.uk/helloworld/HelloWorldPortType/EchoResponse
http://tutorial1.wsrf.dl.ac.uk/helloworld/HelloWorldPortType/EchoRequest </wsa:Action>
</wsa:Action> <wsa:From soapenv:mustUnderstand="0">
<wsa:From soapenv:mustUnderstand="0"> <wsa:Address>
<wsa:Address> http://localhost:8082/wsrf/services/HelloWorldService
http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous </wsa:Address>
</wsa:Address> </wsa:From>
</wsa:From> <wsa:RelatesTo
</soapenv:Header> RelationshipType="wsa:Reply" soapenv:mustUnderstand="0">
<soapenv:Body> uuid:88c65b40-dcc1-11d9-ae7c-b8ea2ebe6b67
<echoRequest xmlns="http://tutorial1.wsrf.dl.ac.uk/helloworld"> </wsa:RelatesTo>
Rob Allan </soapenv:Header>
</echoRequest> <soapenv:Body>
</soapenv:Body> <echoResponse xmlns="http://tutorial1.wsrf.dl.ac.uk/helloworld">
</soapenv:Envelope> Hello Rob Allan !
</echoResponse>
</soapenv:Body>
</soapenv:Envelope>

Note: QName in HelloWorld.java and Client1.java should be same, otherwise it will be error, surprisingly if QName in HelloWorld.java
and WSDL are different, client still works. My understanding is all three should be exactly same, better to test again before conclusion.

WSRF Based Hello World Web Service

Das könnte Ihnen auch gefallen