Deploying Web Services with AXIS
-
Upload
dillon-hooper -
Category
Documents
-
view
49 -
download
0
description
Transcript of Deploying Web Services with AXIS
1
Deploying Web Services with AXIS
Deploying Web Services with AXIS
Representation and Management of Data on the Web
2
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)
3
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
4
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
5
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
6
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/
7
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 shared
friendsnet axis lib classes
Classes were added for you
The directory that you need to copy
8
http://computer-that-run-tomcat:port/axis
Validate installation
View deployed services
9
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
10
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
11
A Client in a Web Service
WebServer
Request a WSDL file
Receive a WSDL
ReturnedWSDL
Parse
12
A Client in a Web Service
WebServer
SOAP Request
Create
Send SOAP Request
Receive SOAP Response
SOAP Response
Parse
13
Creating a Client
1. Create a Service object2. Create a Call object3. Set the endpoint URL, i.e., the
destination for the SOAP message4. Define the operation (method) name of
the Web Service5. Invoke the desired service, passing in
an array of parameters
14
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();
15
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());
}
}
}
16
POST http://nagoya.apache.org:5049/axis/services/echo HTTP/1.0Content-Type: text/xml; charset=utf-8Accept: application/soap+xml, application/dime, multipart/related, text/*User-Agent: Axis/1.1Host: nagoya.apache.org:5049Cache-Control: no-cachePragma: no-cacheSOAPAction: ""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> </soapenv:Body>
The HTTP RequestThe HTTP Request
17
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/wsprimegenerator.exe/wsdl/IPrimeGenerator
18
<?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>
The WSDL of the Service
19
<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
20
<binding name="IPrimeGeneratorbinding" type="tns:IPrimeGenerator"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="primegenerator"> <soap:operation soapAction="urn:UnitIPrimeGenerator-IPrimeGenerator#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
21
<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
22
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");
23
/* 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";
24
/* 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); } }}
25
26
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 --
The HTTP Request
27
<?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>
28
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)
The HTTP Response
29
<?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>
30
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
31
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
32
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
33
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);
34
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!
35
Example: a Calculator Service
public class SimpleCalculator {
public int add(int i1, int i2) { return i1 + i2; }
public int subtract(int i1, int i2) { return i1 - i2; }}
We create a Java Class
We rename the file SimpleCalculator.jws
We put the file under webapps/axis
36
http://computer-that-runs-tomcat:port/axis/SimpleCalculator.jws
37
The Client For the Calculatorimport 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; }
38
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); }}
39
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
Tomcat
WEB-INF
jwsClassesclasses
AxisServlet.class
http://host:8090/axis/SimpleCalculator.jws2HTTP Request
SimpleCalculator.jws
1
40
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
Tomcat
WEB-INF
jwsClassesclasses
AxisServlet.class SimpleCalculator.class
4
3 The HTTP Request is “translated” to a request for
http://host:8090/axis/servlet/AxisServlet
The original URL is still known!
SimpleCalculator.jws
1
41
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
Tomcat
WEB-INF
jwsClassesclasses
AxisServlet.class SimpleCalculator.class
4
5 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
SimpleCalculator.jws
1
42
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
43
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/*
44
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
java org.apache.axis.client.AdminClient -p port deploy-file.wsdd
45
Creating a Service
1. Create a Java class2. 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!
46
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
47
The Service Code
package dbi;
public class PowerService {
public int power(int a, int n) {
return (int)Math.pow(a,n);
}
}
$CATALINA_BASE/webapps/axis/WEB-INF/classes/dbi/PowerService.class
We compile the class and put the file in the right directory
48
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
49
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";
A Client that Calls the Power Service
50
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?
Is it important from which directory I call the client?Is it important from which computer I call the client?
51
The HTTP Request
POST /axis/services/dbiPowerService HTTP/1.0content-type:text/xml; charset=utf-8accept:application/soap+xml, application/dime,
multipart/related, text/*user-agent:Axis/1.1host:mangal.cs.huji.ac.il:8090cache-control:no-cachepragma:no-cachesoapaction:""content-length:499
52
<?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>
53
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
<?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>
The HTTP Response
54
<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>
The WSDL (1)
55
<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>
The WSDL (2)
56
<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>
The WSDL (3)
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>
</deployment> Required namespaces:Saying that this is a deployment fileof axis
Required namespaces:Saying that this is a deployment fileof axis
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>
The name of the serviceThe name of the service The service is an RPC (not document)
The service is an RPC (not document)
59
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>
The class w.r.t. axis/WEB-INF/classes/The class w.r.t. axis/WEB-INF/classes/
The scope of the created objectThe scope of the created object
Which methods can be calledWhich methods can be called
60
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
61
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
After undeployment you cannot call the service anymore
On which computer to apply?
62
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
63
Standard mappings from WSDL to Java
xsd:base64Binary byte[]xsd:boolean booleanxsd:byte bytexsd:dateTime java.util.Calendarxsd:decimal java.math.BigDecimalxsd:double doublexsd:float floatxsd:hexBinary byte[]xsd:int intxsd:integer java.math.BigIntegerxsd:long longxsd:Qname javax.xml.namespace.QNamexsd:short shortxsd:string java.lang.String
64
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)
65
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?
66
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
67
WSDL2Java Mappings
WSDL clause Java class(es) generatedFor each entry in the A java classtype section A holder if this type is
used as an inout/out parameter
For each portType A java interfaceFor each binding A stub classFor each service A service interface A service implementation (the locator)
68
Using Reflection for Implementing Web Services
69
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
70
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
71
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>
72
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
}
73
Our Simple SOAP Processorimport 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"));
74
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>");
} } }
75
A Class and a Method
package hello;
public class HelloServer {
public String sayHelloTo(String name) {
Return(new String(“Hello “ + name +
“, How are you doing?”);
}
…
}
package hello;
public class HelloServer {
public String sayHelloTo(String name) {
Return(new String(“Hello “ + name +
“, How are you doing?”);
}
…
}
76
77
78
Scoping
• What did the scoping of the Web Service correspond to: (request?, session?, application?)
• How would the implementation differ if the scoping was different?
79
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?
80
A Possible Solution
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
FriendsDatabase
1. Put the FriendsDatabase class under shared
2. Use a static field of FriendsDatabase to hold the login argument
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?