Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Deploying Web Services
with AXIS
Representation and Management
of Data on the Web
1
Web Services
• Web services are methods that a
remote application can call
• The methods are invoked through usual
Web protocols (e.g., HTTP)
• Calling a method:
– Discovery (UDDI)
– Description (WSDL)
– Invocation (SOAP)
2
What is AXIS
• Axis is essentially a SOAP engine – a
framework for constructing SOAP
processors such as clients, servers,
gateways
• AXIS implements the interfaces of
JAX-RPC (remote procedure calls in
Java, using XML)
• AXIS = Apache EXtensible Interaction
System
3
Remote Method Invocation is not a New Idea
• java.rmi has been in Java since Java’s early
versions
• In Java RMI, objects can invoke methods of
objects that reside on a remote computer
(RMI = Remote Method Invokation)
• So, what has been changed:
– Using HTTP and port 80 we can bypass the
firewall
– Using agreed protocols, Java can invoke methods
that were not written in Java (e.g., .NET methods)
and vice versa
– A complex registry procedure has been required in
RMI
4
AXIS Includes
• Axis isn't just a SOAP engine – it also
includes:
– a simple stand-alone server
– a server which plugs into servlet engines such as
Tomcat
– extensive support for the Web Service Description
Language (WSDL)
– emitter tooling that generates Java classes from
WSDL
– a tool for monitoring TCP/IP packets
5
AXIS Installation
• AXIS works inside a Servlet container (e.g.,
Tomcat)
• You should add to your Tomcat libs some jar
files: axis.jar, saaj.jar, wsdl4j.jar, …
• You need to include several jar files in your
CLASSPATH
• This has already been done for you
– The needed CLASSPATH definitions where added
to dbi.cshrc
– The needed jar files were added to
$CATALINA_BASE/shared/lib/
6
Working With AXIS
• AXIS uses Servlets that Tomcat apply
• You should copy the axis directory from
dbi to your webapps directory:
cp –r ~dbi/tomcat/axis $CATALINA_BASE/webapps/
$CATALINA_BASE
webapps
friendsnet
shared
axis
The directory that
you need to copy
lib
Classes were
added for you
classes
7
http://computer-that-run-tomcat:port/axis
Validate installation
View deployed services
8
What We Would Like to Create
• Client applications: applications that
can call a remote service
• Services: methods that can be called
by remote applications
• Service descriptions: WSDL files that
describe our methods
9
Will We Do a Lot of XML Parsing?
• You will not directly read or write SOAP
messages
• Instead, use Java methods that create
request and analyze result
• Use the AxisServlet that actually
includes a SOAP processor
• Code the Client Application and the
Service Application
10
A Client in a Web Service
Request
a WSDL
file
Receive
a WSDL
Web
Server
Parse
Returned
WSDL
11
A Client in a Web Service
SOAP
Request
Create
Parse
Send
SOAP
Request
Receive
SOAP
Response
Web
Server
SOAP
Response
12
Creating a Client
1. Create a Service object
2. Create a Call object
3. Set the endpoint URL, i.e., the
destination for the SOAP message
4. Define the operation (method) name of
the Web Service
5. Invoke the desired service, passing in
an array of parameters
13
A Simple Client Example
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class TestClient {
public static void main(String [] args) {
try {
String endpoint =
"http://nagoya.apache.org:5049/axis/services/echo";
Service service = new Service();
Call call = (Call) service.createCall();
14
A Simple Client Example
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/",
"echoString"));
String ret = (String) call.invoke( new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
15
POST http://nagoya.apache.org:5049/axis/services/echo HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.1
Host: nagoya.apache.org:5049
Cache-Control: no-cache
The HTTP Request
Pragma: no-cache
SOAPAction: ""
Content-Length: 461
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:echoString
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://soapinterop.org/">
<ns1:arg0 xsi:type="xsd:string">Hello!</ns1:arg0>
</ns1:echoString>
16
</soapenv:Body>
Example: A Client that
Uses WSDL
• We create an application that calls a
remote Web service
• In our example the remote Web service
produces prime numbers in a given
range
• The service is in URL
http://www.jusufdarmawan.com/wsprimegene
rator.exe/wsdl/IPrimeGenerator
17
The WSDL of the Service
<?xml version="1.0" ?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
name="IPrimeGeneratorservice"
targetNamespace="http://www.borland.com/soapServices/"
xmlns:tns="http://www.borland.com/soapServices/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<message name="primegeneratorRequest">
<part name="valstart" type="xs:string" />
<part name="valend" type="xs:string" />
</message>
<message name="primegeneratorResponse">
<part name="return" type="xs:string" />
</message>
18
<portType name="IPrimeGenerator">
<operation name="primegenerator">
<input message="tns:primegeneratorRequest" />
<output message="tns:primegeneratorResponse" />
</operation>
</portType>
String primegenerator(String valstart, String valend)
Defining the function
19
<binding name="IPrimeGeneratorbinding" type="tns:IPrimeGenerator">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="primegenerator">
<soap:operation soapAction="urn:UnitIPrimeGeneratorIPrimeGenerator#primegenerator" />
<input>
<soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:UnitIPrimeGenerator-IPrimeGenerator" />
</input>
<output>
<soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:UnitIPrimeGenerator-IPrimeGenerator" />
</output>
</operation>
</binding>
Binding the method as an RPC
20
<service name="IPrimeGeneratorservice">
<port name="IPrimeGeneratorPort"
binding="tns:IPrimeGeneratorbinding">
<soap:address
location="http://www.jusufdarmawan.com/wsprimegenerator.
exe/soap/IPrimeGenerator" />
</port>
</service>
</definitions>
The Service URL
21
The Client Source Code
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import java.net.URL;
public class PrimeGenerator {
public static void main(String[] argv) {
try {
/* Set the porxy parameters */
System.setProperty("http.proxyHost", "wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort", "8080");
22
/* Set the service parameters */
String defaultNS = null;
String endpoint = null;
URL wsdl = new URL("http://www.jusufdarmawan.com/
wsprimegenerator.exe/wsdl/IPrimeGenerator");
QName serviceName = new
QName("http://www.borland.com/soapServices/",
"IPrimeGeneratorservice");
String method = "primegenerator";
String port = "IPrimeGeneratorPort";
/* Set the service arguments */
String start = "200";
String end = "300";
23
/* Invoke the service */
Service service = new Service(wsdl, serviceName);
Call call = (Call) service.createCall(new
QName(port),
new QName(method));
String value = (String)call.invoke(new Object[] { start, end } );
System.out.println("Primes between " + start +" and " +
end + ": " + value);
} catch (Exception exp) {
exp.printStackTrace(System.err);
}
}
}
24
25
The HTTP Request
POST /wsprimegenerator.exe/soap/IPrimeGenerator HTTP/1.0
content-type:text/xml; charset=utf-8
accept:application/soap+xml, application/dime, multipart/related, text/*
user-agent:Axis/1.1
host:www.jusufdarmawan.com
cache-control:no-cache
pragma:no-cache
soapaction:"urn:UnitIPrimeGenerator-IPrimeGenerator#primegenerator"
content-length:540
-- empty line -26
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:primegenerator
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="urn:UnitIPrimeGenerator-IPrimeGenerator">
<valstart xsi:type="xsd:string">200</valstart>
<valend xsi:type="xsd:string">300</valend>
</ns1:primegenerator>
</soapenv:Body>
</soapenv:Envelope>
27
The HTTP Response
HTTP/1.0 200 OK
Date: Tue, 08 Jun 2004 20:10:16 GMT
Content-Length: 603
Content-Type: text/xml
Server: Microsoft-IIS/5.0
X-Powered-By: ASP.NET
Content:
Via: 1.1 proxy7 (NetCache NetApp/5.5R4)
28
<?xml version="1.0" encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<NS1:primegeneratorResponse
xmlns:NS1="urn:UnitIPrimeGenerator-IPrimeGenerator"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:string">
211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
281, 283, 293</return>
</NS1:primegeneratorResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
29
Service
• Service()
– the constructor assumes that the caller will set the
appropriate fields by hand rather than getting them
from the WSDL
• Service(java.io.InputStream wsdlInputStream,
QName serviceName)
– Constructs a new Service object for the service in
the WSDL document in the wsdlInputStream and
serviceName parameters
30
Creating a Call
•
Call createCall()
– Creates a new Call object with no prefilled data
• Call createCall(QName portName,
QName operationName)
– Creates a new Call object - will prefill as much info
from the WSDL as it can
31
Call
• Used to actually invoke the Web service
• You can invoke the operation
associated with the call using
invoke(…)
• invoke(Object[] params)
– Invokes the operation associated with the
call using the passed in parameters as the
arguments to the method
32
Setting Types
• You can set parameters using the
method addParamether(…)
• You can set the returned type using
setReturnedType(…)
call.addParameter("testParam",
org.apache.axis.Constants.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
33
Creating a Service
•
There is a fast and easy way of crating
a service:
1. Create a Java class myClass.java
2. Rename your class to end with jws:
myClass.jws
3. Put the jws file under the directory
$CATALINA_BASE/webapps/axis/
4. That is all. Now you can call the service!
34
Example: a Calculator Service
public class SimpleCalculator {
public int add(int i1, int i2)
{
return i1 + i2;
}
We create a Java Class
public int subtract(int i1, int i2)
{
return i1 - i2;
}
}
We rename the file SimpleCalculator.jws
We put the file under webapps/axis
35
http://computer-that-runs-tomcat:port/axis/SimpleCalculator.jws
36
The Client For the Calculator
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;
import javax.xml.rpc.ParameterMode;
public class SimpleCalcClient {
public static void main(String [] args) throws Exception {
String endpoint = "http://mangal.cs.huji.ac.il:8999/axis/SimpleCalculator.jws";
if (args == null || args.length != 3) {
System.err.println("Usage: SimpleCalcClient <add|subtract> arg1 arg2");
return;
}
String method = args[0];
if (!(method.equals("add") || method.equals("subtract"))) {
System.err.println("Usage: CalcClient <add|subtract> arg1 arg2");
return;
37
}
Integer i1 = new Integer(args[1]);
Integer i2 = new Integer(args[2]);
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( method );
call.addParameter( "op1", XMLType.XSD_INT, ParameterMode.IN );
call.addParameter( "op2", XMLType.XSD_INT, ParameterMode.IN );
call.setReturnType( XMLType.XSD_INT );
Integer ret = (Integer) call.invoke( new Object [] { i1, i2 });
System.out.println("Got result : " + ret);
}
}
38
Tomcat
$CATALINA_BASE
webapps
friendsnet
1
shared
axis
lib
classes
WEB-INF
SimpleCalculator.jws
classes
jwsClasses
AxisServlet.class
HTTP Request
2
http://host:8090/axis/SimpleCalculator.jws
39
Tomcat
$CATALINA_BASE
webapps
friendsnet
1
shared
axis
lib
WEB-INF
SimpleCalculator.jws
classes
jwsClasses
4
AxisServlet.class
3
classes
SimpleCalculator.class
The HTTP Request is “translated” to a request for
http://host:8090/axis/servlet/AxisServlet
The original URL is still known!
40
Tomcat
$CATALINA_BASE
webapps
friendsnet
1
shared
axis
lib
WEB-INF
SimpleCalculator.jws
classes
jwsClasses
4
AxisServlet.class
5
classes
SimpleCalculator.class
1.
The class SimpleCalculator is compiled and
dynamically loaded
2.
The SOAP request is parsed and analyzed
3.
A response is created by the SimpleCalculator
4.
The result is wrapped as a SOAP response an returned
to the caller
HTTP
Response
41
When not to Use jws Files
• When you do not have the Java source
code
• When you don’t want to expose your
code
• When you want to use custom type
mappings
• When you want to use other
configuration options
42
AxisServlet
• Dealing with service calls is done by
AxisServlet
• The following files are mapped to
AxisServlet (in web.xml of the axis
application directory):
– servlet/AxisServlet
– *.jws
– services/*
43
Deploying Services
• When a service is called, the AxisServlet
must know where to look for the application
• Telling where the application can be found is
called "deploying"
• Deploying is a two-step process:
– Create a deployment descriptor file
– Call the java command that deploys the web
application:
java org.apache.axis.client.AdminClient
-p port deploy-file.wsdd
44
Creating a Service
1. Create a Java class
2. Compile the class
3. Put the class under
axis/WEB-INF/classes/the-package-name/
4. Create a deployment descriptor file
mydeploy.wsdd
5. Call the AdminClient Service with the
deployment file as a parameter (in the
computer where Tomcat runs AXIS)
6. You are done and can call the service!
45
Example: A Power Function
• We create a service that computes the
power of two numbers
• We show how to deploy the service
• We demonstrate the service with a
client that calls the service
46
The Service Code
package dbi;
public class PowerService {
public int power(int a, int n) {
return (int)Math.pow(a,n);
}
}
We compile the class and put the file in the right directory
$CATALINA_BASE/webapps/axis/WEB-INF/classes/dbi/PowerService.class
47
Deployment File
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="dbiPowerService" provider="java:RPC">
<parameter name="className" value="dbi.PowerService"/>
<parameter name="scope" value="application"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
We call the file dbideploy.wsdd
java org.apache.axis.client.AdminClient
-p8090 dbideploy.wsdd
After deployment you can call the service
48
A Client that Calls the Power Service
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class PowerClient {
private static final String host = "mangal.cs.huji.ac.il";
private static final int port = 8090;
public static void main(String[] argv) {
try {
int x=2, n=5;
String endpoint = "http://" + host + ":" + port +
"/axis/services/dbiPowerService";
49
call call = (Call) new Service().createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName("power");
Integer value = (Integer)call.invoke(new Object[] {
new Integer(x), new Integer(n)
});
System.out.println(x+"^"+n +"=" + value);
} catch (Exception exp) {
exp.printStackTrace(System.err);
}
}
}
Is it important from which directory I call the client?
Is it important from which computer I call the client?
50
The HTTP Request
POST /axis/services/dbiPowerService HTTP/1.0
content-type:text/xml; charset=utf-8
accept:application/soap+xml, application/dime,
multipart/related, text/*
user-agent:Axis/1.1
host:mangal.cs.huji.ac.il:8090
cache-control:no-cache
pragma:no-cache
soapaction:""
content-length:499
51
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:power
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://dbi/">
<ns1:arg0 xsi:type="xsd:int">2</ns1:arg0>
<ns1:arg1 xsi:type="xsd:int">5</ns1:arg1>
</ns1:power>
</soapenv:Body>
</soapenv:Envelope>
52
HTTP/1.1 200 OK
Content-Type: text/xml;charset=utf-8
Date: Sat, 05 Jun 2004 18:00:02 GMT
Server: Apache-Coyote/1.1
Connection: close
The HTTP
Response
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:powerResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://dbi/">
<ns1:powerReturn xsi:type="xsd:int">32</ns1:powerReturn>
</ns1:powerResponse>
</soapenv:Body>
</soapenv:Envelope>
53
The WSDL (1)
<wsdl:definitions
targetNamespace="http://mangal.cs.huji.ac.il:8090/axis/services/dbiPowerService">
<wsdl:message name="powerResponse">
<wsdl:part name="powerReturn" type="xsd:int"/>
</wsdl:message>
<wsdl:message name="powerRequest">
<wsdl:part name="in0" type="xsd:int"/>
<wsdl:part name="in1" type="xsd:int"/>
</wsdl:message>
<wsdl:portType name="PowerService">
<wsdl:operation name="power" parameterOrder="in0 in1">
<wsdl:input message="impl:powerRequest" name="powerRequest"/>
<wsdl:output message="impl:powerResponse" name="powerResponse"/>
</wsdl:operation>
</wsdl:portType>
54
The WSDL (2)
<wsdl:binding name="dbiPowerServiceSoapBinding" type="impl:PowerService">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="power">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="powerRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dbi" use="encoded"/>
</wsdl:input>
<wsdl:output name="powerResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://mangal.cs.huji.ac.il:8090/axis/services/dbiPowerService"
use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
55
The WSDL (3)
<wsdl:service name="PowerServiceService">
<wsdl:port binding="impl:dbiPowerServiceSoapBinding"
name="dbiPowerService">
<wsdlsoap:address
location="http://mangal.cs.huji.ac.il:8999/axis/services/dbiPowerService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
56
Deployment File
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="dbiPowerService" provider="java:RPC">
<parameter name="className" value="dbi.PowerService"/>
<parameter name="scope" value="application"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
Required namespaces:
Saying that this is a deployment file
of axis
57
Deployment File
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="dbiPowerService" provider="java:RPC">
<parameter name="className" value="dbi.PowerService"/>
<parameter name="scope" value="application"/>
<parameter name="allowedMethods" value="*"/>
</service>
The service is an RPC
The name of the service
(not document)
</deployment>
58
Deployment File
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="dbiPowerService" provider="java:RPC">
<parameter name="className" value="dbi.PowerService"/>
<parameter name="scope" value="application"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
Which methods can be called
The scope of the created object
The class w.r.t. axis/WEB-INF/classes/
59
The Scope of the Object
• Request (the default): a new object is
created for each request, the service instance
is available for the duration of the request,
regardless of forwarding
• Session: a new object is created for each
new session and the service instance is
available for the entire session
• Application: a singleton shared service
instance is used to serve all invocations
60
Undeployment of Services
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name=“dbiPowerService"/>
</undeployment>
We call this file dbiundeploy.wsdd
java org.apache.axis.client.AdminClient
-p8090 dbiundeploy.wsdd
On which
computer
to apply?
After undeployment you cannot call
the service anymore
61
Service Styles
• RPC – a call according to SOAP RPC
conventions
• Document – do not use encoding but maps
XML to Java types
• Wrapped – similar to document, except that
they unwrap the body to individual
parameters
• Message – the services and returns raw XML
in the SOAP envelop, I.e., no type mappings
or data bindings
62
Standard mappings from
WSDL to Java
xsd:base64Binary
xsd:boolean
xsd:byte
xsd:dateTime
xsd:decimal
xsd:double
xsd:float
xsd:hexBinary
xsd:int
xsd:integer
xsd:long
xsd:Qname
xsd:short
xsd:string
byte[]
boolean
byte
java.util.Calendar
java.math.BigDecimal
double
float
byte[]
int
java.math.BigInteger
long
javax.xml.namespace.QName
short
java.lang.String
63
Note on Parameters
• It must be possible to "serialize" the parameters
that the method invoked receives and returns.
Why?
• The following have default
serialization/deserialization:
– primitive types: int, long, double, etc.
– primitive Objects: Integer, Long, Double, String, etc.
– complex Objects: Vector, Enumeration, Hashtable,
arrays
– easy to use JavaBeans (not discussed here)
64
Remote Exceptions
• When you call a Java method an
exception can be thrown
• Consider a case where a client supplies
a bad argument and an exception
occurs in the server (while handling the
service call)
• What should happen?
65
AXIS Support of WSDL
1. When you deploy a service in Axis, users
may then access your service's URL with a
standard web browser and by appending
"?WSDL" to the end of the URL
2. AXIS provides a "WSDL2Java" tool which
builds Java proxies and skeletons for
services with WSDL descriptions
3. AXIS provides a "Java2WSDL" tool which
builds WSDL from Java classes
66
WSDL2Java Mappings
WSDL clause
For each entry in the
type section
For each portType
For each binding
For each service
Java class(es) generated
A java class
A holder if this type is
used as an inout/out parameter
A java interface
A stub class
A service interface
A service implementation
(the locator)
67
Using Reflection for Implementing
Web Services
68
How Could a SOAP Processor be
Implemented?
• No, we won't be implementing a SOAP
Processor in this course
• However, it could be implemented using
reflection
• Reflection is a Java mechanism for
discovering the class/methods/fields of an
object
• Reflection allows you to load classes and
invoke methods
69
Simple SOAP Implementation
• In SOAP, the details about the RPC are in an
XML message
• In our Simple SOAP Implementation
example, details will be in parameters of
HTTP request
• We will allow user to invoke any method of
any class, provided that the method only has
String arguments
• All this is to give us an idea of how a SOAP
processor works
70
Getting Invocation Details from Client
(HTML Form)
<form name="info" method="get" action="servlet/SOAPImitation">
Class Name: <input type="text" name="class"><br>
Method Name: <input type="text" name="method"><br>
<input type="button" value="Set Number of Arguments"
onClick="setArguments()">
<input type="hidden" name="paramNum" value="0">
<p id = "argumentP"></p>
<input type="submit">
</form>
71
Getting Invocation Details from Client
(HTML Form)
function setArguments() {
num = prompt("Enter the number of arguments to the method", 0);
p = document.getElementById("argumentP");
str = ""
for (i = 0 ; i < num ; i++) {
str += "Argument " + i + ": " +
"<input type='text' name='param" + i + "'><br>";
}
p.innerHTML=str;
info.paramNum.value=num
}
72
Our Simple SOAP Processor
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
import java.lang.reflect.*;
public class SoapImitation extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try{
Class objClass = Class.forName(req.getParameter("class"));
int numParams= Integer.parseInt(req.getParameter("paramNum"));
73
Class[] paramClasses = new Class[numParams];
Object[] paramObjs = new Object[numParams];
for (int i = 0 ; i < numParams ; i++) {
paramClasses[i] = Class.forName("java.lang.String");
paramObjs[i] = req.getParameter("param" + i);
}
Method method =
objClass.getMethod(req.getParameter("method"),
paramClasses);
Object result = method.invoke(objClass.newInstance(),
paramObjs);
out.println("<HTML><BODY><h1>Method Result</h1>" +
result + "</BODY></HTML>");
} catch (Exception e) {
out.println("<HTML><BODY>Error!</BODY></HTML>");
} } }
74
A Class and a Method
package hello;
public class HelloServer {
public String sayHelloTo(String name) {
Return(new String(“Hello “ + name +
“, How are you doing?”);
}
…
}
75
76
77
Scoping
• What did the scoping of the Web
Service correspond to: (request?,
session?, application?)
• How would the implementation differ if
the scoping was different?
78
When Web Application Need to
Share Information
• In your implementation of the friendsnet
Web application you will create
instances of the class FriendsDatabase
• Where is the login for accessing the
database is taken from?
• If you will have a service under axis, will
the service be able to create a
FriendsDatabase instance that includes
the login parameter?
79
A Possible Solution
$CATALINA_BASE
webapps
friendsnet
shared
axis
lib
classes
1. Put the FriendsDatabase class under shared
2. Use a static field of FriendsDatabase to hold
the login argument
FriendsDatabase
3. The first time a Servlet in friendsnet creates
an instance of FriendsDatabase, this servlet
sets the login
4. Now, what about servlets of axis?
80