Deploying Web Services with AXIS Representation and Management
Deploying Web Services with AXIS Representation and Management of Data on the Web 1
Web Services • Web services are methods that a remote application 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, wsdl 4 j. 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 Axis. Servlet 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 Test. Client { 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. create. Call(); 14
A Simple Client Example call. set. Target. Endpoint. Address( new java. net. URL(endpoint) ); call. set. Operation. Name(new QName("http: //soapinterop. org/", "echo. String")); String ret = (String) call. invoke( new Object[] { "Hello!" } ); System. out. println("Sent 'Hello!', got '" + ret + "'"); } catch (Exception e) { System. err. println(e. to. String()); } } } 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. w 3. org/2001/XMLSchema" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance"> <soapenv: Body> <ns 1: echo. String soapenv: encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" xmlns: ns 1="http: //soapinterop. org/"> <ns 1: arg 0 xsi: type="xsd: string">Hello!</ns 1: arg 0> </ns 1: echo. String> 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/IPrime. Generator 17
The WSDL of the Service <? xml version="1. 0" ? > <definitions xmlns="http: //schemas. xmlsoap. org/wsdl/" xmlns: xs="http: //www. w 3. org/2001/XMLSchema" name="IPrime. Generatorservice" target. Namespace="http: //www. borland. com/soap. Services/" xmlns: tns="http: //www. borland. com/soap. Services/" xmlns: soap="http: //schemas. xmlsoap. org/wsdl/soap/" xmlns: soapenc="http: //schemas. xmlsoap. org/soap/encoding/"> <message name="primegenerator. Request"> <part name="valstart" type="xs: string" /> <part name="valend" type="xs: string" /> </message> <message name="primegenerator. Response"> <part name="return" type="xs: string" /> </message> 18
<port. Type name="IPrime. Generator"> <operation name="primegenerator"> <input message="tns: primegenerator. Request" /> <output message="tns: primegenerator. Response" /> </operation> </port. Type> String primegenerator(String valstart, String valend) Defining the function 19
<binding name="IPrime. Generatorbinding" type="tns: IPrime. Generator"> <soap: binding style="rpc" transport="http: //schemas. xmlsoap. org/soap/http" /> <operation name="primegenerator"> <soap: operation soap. Action="urn: Unit. IPrime. Generator#primegenerator" /> <input> <soap: body use="encoded" encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" namespace="urn: Unit. IPrime. Generator-IPrime. Generator" /> </input> <output> <soap: body use="encoded" encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" namespace="urn: Unit. IPrime. Generator-IPrime. Generator" /> </output> </operation> </binding> Binding the method as an RPC 20
<service name="IPrime. Generatorservice"> <port name="IPrime. Generator. Port" binding="tns: IPrime. Generatorbinding"> <soap: address location="http: //www. jusufdarmawan. com/wsprimegenerator. exe/soap/IPrime. Generator" /> </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 Prime. Generator { public static void main(String[] argv) { try { /* Set the porxy parameters */ System. set. Property("http. proxy. Host", "wwwproxy. huji. ac. il"); System. set. Property("http. proxy. Port", "8080"); 22
/* Set the service parameters */ String default. NS = null; String endpoint = null; URL wsdl = new URL("http: //www. jusufdarmawan. com/ wsprimegenerator. exe/wsdl/IPrime. Generator; (" QName service. Name = new QName("http: //www. borland. com/soap. Services , "/ "IPrime. Generatorservice ; (" String method = "primegenerator; " String port = "IPrime. Generator. Port; " */ Set the service arguments/* String start = "200; " String end = "300; " 23
/* Invoke the service */ Service service = new Service(wsdl, service. Name); Call call = (Call) service. create. Call(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. print. Stack. Trace(System. err; ( { { { 24
25
The HTTP Request POST /wsprimegenerator. exe/soap/IPrime. Generator 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: Unit. IPrime. Generator-IPrime. Generator#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. w 3. org/2001/XMLSchema" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance"> <soapenv: Body> <ns 1: primegenerator soapenv: encoding. Style="http: //schemas. xmlsoap. org/soap/encoding "/ xmlns: ns 1="urn: Unit. IPrime. Generator-IPrime. Generator<" > valstart xsi: type="xsd: string">200</valstart< > valend xsi: type="xsd: string">300</valend< /> ns 1: primegenerator< /> soapenv: Body< />soapenv: Envelope< 27
The HTTP Response HTTP/1. 0 200 OK Date: Tue, 08 Jun 2004 20: 16 GMT Content-Length: 603 Content-Type: text/xml Server: Microsoft-IIS/5. 0 X-Powered-By: ASP. NET Content: Via: 1. 1 proxy 7 (Net. Cache Net. App/5. 5 R 4) 28
<? xml version="1. 0" encoding='UTF-8'? > <SOAP-ENV: Envelope xmlns: SOAP-ENV="http: //schemas. xmlsoap. org/soap/envelope/" xmlns: xsd="http: //www. w 3. org/2001/XMLSchema" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xmlns: SOAP-ENC="http: //schemas. xmlsoap. org/soap/encoding<"/ > SOAP-ENV: Body< > NS 1: primegenerator. Response xmlns: NS 1="urn: Unit. IPrime. Generator-IPrime. Generator " SOAP-ENV: encoding. Style="http: //schemas. xmlsoap. org/soap/encoding<"/ > return xsi: type="xsd: string<" , 277 , 271 , 269 , 263 , 257 , 251 , 241 , 239 , 233 , 229 , 227 , 223 , 211 />293 , 281 /> return< NS 1: primegenerator. Response< /> 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. Input. Stream wsdl. Input. Stream, QName service. Name) – Constructs a new Service object for the service in the WSDL document in the wsdl. Input. Stream and service. Name parameters 30
Creating a Call • Call create. Call() – Creates a new Call object with no prefilled data • Call create. Call(QName port. Name, QName operation. Name) – 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 add. Paramether(…) • You can set the returned type using set. Returned. Type(…) call. add. Parameter("test. Param", org. apache. axis. Constants. XSD_STRING, javax. xml. rpc. Parameter. Mode. IN); call. set. Return. Type(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 my. Class. java 2. Rename your class to end with jws: my. Class. 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 Simple. Calculator { public int add(int i 1, int i 2) { return i 1 + i 2; } We create a Java Class public int subtract(int i 1, int i 2) { return i 1 - i 2; } } We rename the file Simple. Calculator. jws We put the file under webapps/axis 35
http: //computer-that-runs-tomcat: port/axis/Simple. Calculator. 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. Parameter. Mode; public class Simple. Calc. Client { public static void main(String [] args) throws Exception { String endpoint = "http: //mangal. cs. huji. ac. il: 8999/axis/Simple. Calculator. jws"; if (args == null || args. length != 3) { System. err. println("Usage: Simple. Calc. Client <add|subtract> arg 1 arg 2"); return; } String method = args[0]; if (!(method. equals("add") || method. equals("subtract"))) { System. err. println("Usage: Calc. Client <add|subtract> arg 1 arg 2"); return; 37 }
Integer i 1 = new Integer(args[1]); Integer i 2 = new Integer(args[2]); Service service = new Service(); Call call = (Call) service. create. Call(); call. set. Target. Endpoint. Address( new java. net. URL(endpoint) ); call. set. Operation. Name( method ); call. add. Parameter( "op 1", XMLType. XSD_INT, Parameter. Mode. IN ); call. add. Parameter( "op 2", XMLType. XSD_INT, Parameter. Mode. IN ); call. set. Return. Type( XMLType. XSD_INT ); Integer ret = (Integer) call. invoke( new Object [] { i 1, i 2 }); System. out. println("Got result : " + ret); } } 38
Tomcat $CATALINA_BASE webapps friendsnet 1 shared axis lib classes WEB-INF Simple. Calculator. jws classes jws. Classes Axis. Servlet. class HTTP Request 2 http: //host: 8090/axis/Simple. Calculator. jws 39
Tomcat $CATALINA_BASE webapps friendsnet 1 shared axis lib classes WEB-INF Simple. Calculator. jws classes jws. Classes 4 Axis. Servlet. class Simple. Calculator. class 3 The HTTP Request is “translated” to a request for http: //host: 8090/axis/servlet/Axis. Servlet The original URL is still known! 40
Tomcat $CATALINA_BASE webapps friendsnet 1 shared axis lib classes WEB-INF Simple. Calculator. jws classes jws. Classes 4 Axis. Servlet. class Simple. Calculator. class 5 1. The class Simple. Calculator is compiled and dynamically loaded 2. The SOAP request is parsed analyzed 3. A response is created by the Simple. Calculator 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
Axis. Servlet • Dealing with service calls is done by Axis. Servlet • The following files are mapped to Axis. Servlet (in web. xml of the axis application directory): – servlet/Axis. Servlet – *. jws – services/* 43
Deploying Services • When a service is called, the Axis. Servlet 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. Admin. Client -p port deploy-file. wsdd 44
Creating a Service 1. Create a Java class 2. Compile the class 3. Put the class under -INF/classes/the-package-name/ axis/WEB 4. Create a deployment descriptor file mydeploy. wsdd 5. Call the Admin. Client 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 to deploy the service • We demonstrate the service with a client that calls the service 46
The Service Code package dbi; public class Power. Service { 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/Power. Service. class 47
Deployment File <deployment xmlns="http: //xml. apache. org/axis/wsdd/" xmlns: java="http: //xml. apache. org/axis/wsdd/providers/java"> <service name="dbi. Power. Service" provider="java: RPC"> <parameter name="class. Name" value="dbi. Power. Service"/> <parameter name="scope" value="application"/> <parameter name="allowed. Methods" value="*"/> </service> </deployment> We call the file dbideploy. wsdd java org. apache. axis. client. Admin. Client -p 8090 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 Power. Client { 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/dbi. Power. Service"; 49
call = (Call) new Service(). create. Call; () call. set. Target. Endpoint. Address(new java. net. URL(endpoint; (( call. set. Operation. Name("power; (" Integer value = (Integer)call. invoke(new Object} [] new Integer(x), new Integer(n( ; ({ System. out. println(x+"^"+n +"=" + value; ( { { catch (Exception exp} ( exp. print. Stack. Trace(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/dbi. Power. Service 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. w 3. org/2001/XMLSchema " xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance<" > soapenv: Body< > ns 1: power soapenv: encoding. Style="http: //schemas. xmlsoap. org/soap/encoding "/ xmlns: ns 1="http: //dbi<"/ > ns 1: arg 0 xsi: type="xsd: int">2</ns 1: arg 0< > ns 1: arg 1 xsi: type="xsd: int">5</ns 1: arg 1< /> ns 1: 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. w 3. org/2001/XMLSchema" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance"> <soapenv: Body> <ns 1: power. Response soapenv: encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" xmlns: ns 1="http: //dbi/"> <ns 1: power. Return xsi: type="xsd: int">32</ns 1: power. Return> </ns 1: power. Response> </soapenv: Body> </soapenv: Envelope> 53
The WSDL (1) <wsdl: definitions target. Namespace="http: //mangal. cs. huji. ac. il: 8090/axis/services/dbi. Power. Service"> <wsdl: message name="power. Response"> <wsdl: part name="power. Return" type="xsd: int"/> </wsdl: message> <wsdl: message name="power. Request"> <wsdl: part name="in 0" type="xsd: int"/> <wsdl: part name="in 1" type="xsd: int"/> </wsdl: message> <wsdl: port. Type name="Power. Service"> <wsdl: operation name="power" parameter. Order="in 0 in 1"> <wsdl: input message="impl: power. Request" name="power. Request"/> <wsdl: output message="impl: power. Response" name="power. Response"/> </wsdl: operation> </wsdl: port. Type> 54
The WSDL (2) <wsdl: binding name="dbi. Power. Service. Soap. Binding" type="impl: Power. Service"> <wsdlsoap: binding style="rpc" transport="http: //schemas. xmlsoap. org/soap/http"/> <wsdl: operation name="power"> <wsdlsoap: operation soap. Action=""/> <wsdl: input name="power. Request"> <wsdlsoap: body encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" namespace="http: //dbi" use="encoded"/> </wsdl: input> <wsdl: output name="power. Response"> <wsdlsoap: body encoding. Style="http: //schemas. xmlsoap. org/soap/encoding/" namespace="http: //mangal. cs. huji. ac. il: 8090/axis/services/dbi. Power. Service" use="encoded"/> </wsdl: output> </wsdl: operation> </wsdl: binding> 55
The WSDL (3) <wsdl: service name="Power. Service"> <wsdl: port binding="impl: dbi. Power. Service. Soap. Binding" name="dbi. Power. Service"> <wsdlsoap: address location="http: //mangal. cs. huji. ac. il: 8999/axis/services/dbi. Power. Service"/> </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="dbi. Power. Service" provider="java: RPC"> <parameter name="class. Name" value="dbi. Power. Service"/> <parameter name="scope" value="application"/> <parameter name="allowed. Methods" 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="dbi. Power. Service" provider="java: RPC"> <parameter name="class. Name" value="dbi. Power. Service"/> <parameter name="scope" value="application"/> <parameter name="allowed. Methods" 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="dbi. Power. Service" provider="java: RPC"> <parameter name="class. Name" value="dbi. Power. Service"/> <parameter name="scope" value="application"/> <parameter name="allowed. Methods" 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=“dbi. Power. Service"/> </undeployment> We call this file dbiundeploy. wsdd java org. apache. axis. client. Admin. Client -p 8090 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: base 64 Binary xsd: boolean xsd: byte xsd: date. Time xsd: decimal xsd: double xsd: float xsd: hex. Binary xsd: integer xsd: long xsd: Qname xsd: short xsd: string byte[] boolean byte java. util. Calendar java. math. Big. Decimal double float byte[] int java. math. Big. Integer 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 Java. Beans (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 "WSDL 2 Java" tool which builds Java proxies and skeletons for services with WSDL descriptions 3. AXIS provides a "Java 2 WSDL" tool which builds WSDL from Java classes 66
WSDL 2 Java Mappings WSDL clause For each entry in the type section For each port. Type 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"> Method Name: <input type="text" name="method"> <input type="button" value="Set Number of Arguments" on. Click="set. Arguments()"> <input type="hidden" name="param. Num" value="0"> <p id = "argument. P"></p> <input type="submit"> </form> 71
Getting Invocation Details from Client (HTML Form) function set. Arguments() { num = prompt("Enter the number of arguments to the method", 0); p = document. get. Element. By. Id("argument. P"); str = "" for (i = 0 ; i < num ; i++) { str += "Argument " + i + ": " + "<input type='text' name='param" + i + "'> "; } p. inner. HTML=str; info. param. Num. value=num } 72
Our Simple SOAP Processor import java. io. *; import javax. servlet. http. *; import java. lang. reflect. *; public class Soap. Imitation extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); try{ Class obj. Class = Class. for. Name(req. get. Parameter("class")); int num. Params= Integer. parse. Int(req. get. Parameter("param. Num")); 73
Class[] param. Classes = new Class[num. Params]; Object[] param. Objs = new Object[num. Params]; for (int i = 0 ; i < num. Params ; i++) { param. Classes[i] = Class. for. Name("java. lang. String"); param. Objs[i] = req. get. Parameter("param" + i); } Method method = obj. Class. get. Method(req. get. Parameter("method"), param. Classes); Object result = method. invoke(obj. Class. new. Instance(), param. Objs); out. println("<HTML><BODY><h 1>Method Result</h 1>" + result + "</BODY></HTML>"); } catch (Exception e) { out. println("<HTML><BODY>Error!</BODY></HTML>"); } } } 74
A Class and a Method package hello; public class Hello. Server { public String say. Hello. To(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 Friends. Database • 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 Friends. Database instance that includes the login parameter? 79
A Possible Solution $CATALINA_BASE webapps friendsnet shared axis lib classes 1. Put the Friends. Database class under shared 2. Use a static field of Friends. Database to hold the login argument Friends. Database 3. The first time a Servlet in friendsnet creates an instance of Friends. Database, this servlet sets the login 4. Now, what about servlets of axis? 80
- Slides: 80