1 deploying web services with axis representation and management of data on the web

80
1 Deploying Web Services with AXIS Representation and Management of Data on the Web

Post on 19-Dec-2015

215 views

Category:

Documents


2 download

TRANSCRIPT

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?