Upload
peigi
View
40
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Handling Web Services with Apache AXIS. Web-Service Review. By Examples. POST /wsprimegenerator.exe/soap/IPrimeGenerator HTTP/1.0 Content-Type: text/xml; charset=utf-8 Host: www.jusufdarmawan.com SOAPAction: "urn:UnitIPrimeGenerator-IPrimeGenerator#primegenerator" Content-Length: 527 - PowerPoint PPT Presentation
Citation preview
Handling Web Services Handling Web Services with Apache AXISwith Apache AXIS
Web-Service ReviewWeb-Service Review
By Examples ...
POST /wsprimegenerator.exe/soap/IPrimeGenerator HTTP/1.0Content-Type: text/xml; charset=utf-8Host: www.jusufdarmawan.comSOAPAction: "urn:UnitIPrimeGenerator-IPrimeGenerator#primegenerator"Content-Length: 527
<?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">12</valstart> <valend xsi:type="xsd:string">120</valend> </ns1:primegenerator> </soapenv:Body></soapenv:Envelope>
A request to A request to www.jusufdarmawan.comwww.jusufdarmawan.com
HTTP/1.0 200 OKDate: Mon, 09 May 2005 20:58:35 GMTContent-Length: 619Content-Type: text/xmlServer: Microsoft-IIS/5.0X-Powered-By: ASP.NET
<?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">13,17,19,23,29,31, 37, 41,43, 47,
53,59,61,67,71,73,79,83,89,97,101,103,107,109,113</return> </NS1:primegeneratorResponse> </SOAP-ENV:Body></SOAP-ENV:Envelope>
The ResponseThe Response
POST /soap HTTP/1.0SOAPAction: ""Content-Length: 520
<?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:getRate soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:xmethods-CurrencyExchange">
<country1 xsi:type="xsd:string">Euro</country1> <country2 xsi:type="xsd:string">Israel</country2> </ns1:getRate> </soapenv:Body></soapenv:Envelope>
A request to A request to services.xmethods.netservices.xmethods.net
HTTP/1.0 200 OKDate: Sat, 07 May 2005 23:26:21 GMTContent-Length: 492Content-Type: text/xml
<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
<soap:Body> <n:getRateResponse xmlns:n='urn:xmethods-CurrencyExchange'>
<Result xsi:type='xsd:float'>5.5825</Result> </n:getRateResponse> </soap:Body></soap:Envelope>
The ResponseThe Response
<?xml version="1.0"?>
<definitions name="CurrencyExchangeService" targetNamespace="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl" xmlns:tns="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="getRateRequest"> <part name="country1" type="xsd:string"/> <part name="country2" type="xsd:string"/> </message>
<message name="getRateResponse"> <part name="Result" type="xsd:float"/> </message>
<portType name="CurrencyExchangePortType"> <operation name="getRate"> <input message="tns:getRateRequest" name="getRate"/> <output message="tns:getRateResponse" name="getRateResponse"/> </operation></portType>
A WSDL ExampleA WSDL Example
<binding name="CurrencyExchangeBinding" type="tns:CurrencyExchangePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getRate"> <soap:operation soapAction=""/>
<input name="getRate"> <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input>
<output name="getRateResponse"> <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation></binding>
<service name="CurrencyExchangeService"> <documentation>Returns the exchange rate between the two currencies</documentation> <port name="CurrencyExchangePort" binding="tns:CurrencyExchangeBinding"> <soap:address location="http://services.xmethods.net:80/soap"/> </port></service></definitions>
WSDL ElementsWSDL Elements
ServiceService PortPort*
Port TypePort TypeOperationOperation *
BindingBindingInputInput OutputOutput
AApache Epache EXXtensible tensible IInteraction nteraction SSystemystem
(Axis)(Axis)
What is AXISWhat is AXIS
• Axis is essentially a SOAP engine – a framework for constructing SOAP processors- clients side
- server side
• Axis implements the interfaces of JAX-RPC (XML-based remote procedure calls in Java)
• AXIS = Apache Extensible Interaction System
Remote Method Invocation is not a New Remote Method Invocation is not a New IdeaIdea
• 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 Invocation)
• So, what has been changed?- Using HTTP for communication
- 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
AXIS IncludesAXIS Includes
• Axis package includes: - a simple stand-alone server
- a server which plugs into servlet engines such as Tomcat
- tools for Web service invocation
- extensive support for the Web Service Description Language (WSDL)
- emitter tooling that generates Java classes from WSDL
- and more
What We Would Like to CreateWhat We Would Like to Create
• Client applications: applications that can call a remote Web service
• Services: methods that can be called by remote applications
• Service descriptions: WSDL files that describe our methods
Client ApplicationsClient Applications
Calling Web ServicesCalling Web Services
• By now, we already know how to invoke a remote Web service in Java:- Open a socket to the remote server
- Through the socket, send a SOAP request wrapped by a HTTP request
- Parse the response (e.g., using SAX/DOM)
• However, this approach is cumbersome, and most of it can be automated
Invoking Services with ApacheInvoking Services with Apache
• Axis includes comfortable tools for managing calls to Web services
• The programmer configures the request for the Web service using a friendly API- with, or without considering the WSDL
• According to the configuration, a method invocation is transformed into a SOAP request that is sent to the remote server
Invoking Services with AxisInvoking Services with Axis
• To invoke an operation of a Web service, do the following:- Construct a Service instance
- Using the Service instance, generate a Call instance
- Configure the Call instance
- Invoke the call
import org.apache.axis.client.*;import javax.xml.namespace.QName;import javax.xml.rpc.ParameterMode;import javax.xml.rpc.encoding.XMLType;
public class CurrencyExchange1 {
public static void main(String[] args) throws Exception { System.setProperty("http.proxyHost","wwwproxy.huji.ac.il"); System.setProperty("http.proxyPort","8080");
String endpointUrl = "http://services.xmethods.net:80/soap"; String nsuri = "urn:xmethods-CurrencyExchange";
Service service = new Service(); Call call = (Call) service.createCall();
Example: Currency ExchangeExample: Currency Exchange
call.setTargetEndpointAddress(endpointUrl); call.setOperationName(new QName(nsuri,"getRate")); call.addParameter("country1", XMLType.SOAP_STRING, ParameterMode.IN); call.addParameter("country2", XMLType.SOAP_STRING, ParameterMode.IN);
call.setReturnType(XMLType.SOAP_FLOAT); Object ret = call.invoke(new Object[] {"Euro","Israel"});
System.out.println(ret); }}
Example: Currency Exchange Example: Currency Exchange (cont)(cont)
Using the WSDLUsing the WSDL
• Axis can read a given WSDL and configure the service as much as possible from that WSDL
• Instead of using the default constructor, construct the service using the following constructor:
Service(String wsdlLocation, QName serviceName)
• Also, supply the port to get a prefilled Call object
• In this approach, you usually need to know the following about the service: - the WSDL URL, the service name, the namespace uri, the
operation name and port and the expected arguments
public class CurrencyExchange2 { public static void main(String[] args) throws Exception { System.setProperty("http.proxyHost","wwwproxy.huji.ac.il"); System.setProperty("http.proxyPort","8080");
String wsdl = "http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl";
String nsuri = "http://www.xmethods.net/sd/CurrencyExchangeService.wsdl";
String sName = "CurrencyExchangeService", String oName = "getRate";
Service service = new Service(wsdl, new QName(nsuri,sName));
String port = service.getPorts().next().toString(); Call call = (Call)service.createCall (new QName(nsuri,port), new QName(nsuri,oName));
System.out.println(call.invoke(new Object[] {"UK","Israel"}));}
The WSDL2Java ApplicationThe WSDL2Java Application
• Axis provides a mechanism for communicating with a Web service using stubs
• That is, generation of regular Java classes that have an interface similar to that of the Web service and implementation that wraps Web service management
• Invoke class WSDL2Java in order to create the required Java classes
An ExampleAn Example
Using The Generated ClassesUsing The Generated Classes
import net.xmethods.www.sd.CurrencyExchangeService_wsdl.*;public class CurrencyExchange3 {
public static void main(String[] args) throws Exception { CurrencyExchangeService ce = new CurrencyExchangeServiceLocator(); CurrencyExchangePortType cep = ce.getCurrencyExchangePort(); float rate = cep.getRate("USA","Israel"); System.out.println("Rate: " + rate); }}
Generated ClassesGenerated Classes
• WSDL2Java generates the following:
- A service interface and a service implementation (locator) for each service
- A stub class for each binding
- An interface for each port type• This interface contains methods that correspond to
the operations of the port type
- A class for each complex type
Server ApplicationsServer Applications
AXIS InstallationAXIS 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 are in $CATALINA_BASE/shared/lib/
AXIS Installation (cont)AXIS Installation (cont)
• You need to copy the Axis application to your Tomcat's application directory:
cp -r ~dbi/tomcat/axis/ $CATALINA_BASE/webapps
$CATALINA_BASE
webapps shared
myapplication axis lib classes
Classes were added for you
The directory that you need to copy
Creating a Web ServiceCreating a Web Service
• Next, we will see how we can create and publish a Web service using the Axis plugin in Tomcat
1. Generate the Implementing Class1. Generate the Implementing Class
package myws;public class Power { public int power(int a, int n) { return (int)Math.pow(a,n); }}
$CATALINA_BASE/webapps/axis/classes/myws/Power.class
2. Deploy the Service using Web 2. Deploy the Service using Web Service Deployment DescriptorService Deployment Descriptor
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="mypower" provider="java:RPC"> <parameter name="className" value="myws.Power"/> <parameter name="scope" value="application"/> <parameter name="allowedMethods" value="*"/> </service>
</deployment>
java org.apache.axis.client.AdminClient -hlocalhost -p8090 services.wsdd
services.wsddservices.wsdd
That's it. Call the Service.That's it. Call the Service.import org.apache.axis.client.*;
public class PowerClient {
public static void main(String[] argv)throws Exception { String endpoint = "http://mangal:8090/axis/services/mypower"; Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("power"); Object value = call.invoke(new Object[] {new Integer(2), new Integer(5)}); System.out.println(2+"^"+5 +"=" + value); }}
How Does it Work?How Does it Work?
• The AXIS plugin is simply a Web application that resides in Tomcat (under webapps/)
• The Servlet AxisServlet of this application is responsible for invoking services
• All URLs of the form /services/* are mapped to the AxisServlet- Where is that written?
How Does it Work? (cont)How Does it Work? (cont)
• The wsdd file defines mappings between a Web service elements to a Java class elements- I.e., names, methods, etc.
• The class AdminClient sends a request to the application to register the service based on the wsdd content
• When a SOAP request arrives, the AxisServlet object parses the request and invokes the corresponding method of the class associated with the service URL
The Deployment DescriptorThe Deployment Descriptor
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="mypower" provider="java:RPC"> <parameter name="className" value="myws.Power"/> <parameter name="scope" value="application"/> <parameter name="allowedMethods" value="*"/> </service>
</deployment> services.wsddservices.wsdd
The Scope of the ObjectThe 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
Undeploying a ServiceUndeploying a Service
<undeployment xmlns="http://xml.apache.org/axis/wsdd/"> <service name="mypower"/></undeployment>
java org.apache.axis.client.AdminClient -hlocalhost -p8090 undeploy.wsdd
undeploy.wsddundeploy.wsdd
Implementing ClassesImplementing Classes
• The class that implements the Web service must be accessible to the Axis Servlet
• Hence, this class should reside in a package in one of the directories - $CATALINA_BASE/webapps/axis/WEB-INF/classes
- $CATALINA_BASE/shared/classes (classes that are required for other applications besides Axis)
• Of course, all helper classes should be accessible to the Axis application too
The Service WSDLThe Service WSDL
• Axis automatically provides a WSDL for each deployed service
• To get the WSDL, use the service URL with the empty argument wsdl
http://localhost:8090/axis/services/mypower?wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://localhost/axis/services/mypower" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost/axis/services/mypower" xmlns:intf="http://localhost/axis/services/mypower" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="powerResponse"> <wsdl:part name="powerReturn" type="xsd:int"/> </wsdl:message> <wsdl:message name="powerRequest"> <wsdl:part name="a" type="xsd:int"/> <wsdl:part name="n" type="xsd:int"/> </wsdl:message>
Power-Service WSDLPower-Service WSDL
<wsdl:portType name="Power"> <wsdl:operation name="power" parameterOrder="a n"> <wsdl:input message="impl:powerRequest" name="powerRequest"/> <wsdl:output message="impl:powerResponse" name="powerResponse"/> </wsdl:operation></wsdl:portType>
<wsdl:binding name="mypowerSoapBinding" type="impl:Power"> <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://myws" use="encoded"/>
</wsdl:input> <wsdl:output name="powerResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/axis/services/mypower" use="encoded"/>
</wsdl:output> </wsdl:operation></wsdl:binding>
<wsdl:service name="PowerService"> <wsdl:port binding="impl:mypowerSoapBinding"
name="mypower"> <wsdlsoap:address location="http://localhost/axis/services/mypower"/> </wsdl:port> </wsdl:service></wsdl:definitions>
jws Filesjws Files
• 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 directly under the directory $CATALINA_BASE/webapps/axis/
4. That is all. Now you can call the service!
Example: a Calculator ServiceExample: 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; }}
$CATALINA_BASE/webapps/axis/SimpleCalculator.jws
Service URL:http://server:port/axis/SimpleCalculator.jws
Example: a Calculator ServiceExample: a Calculator Service
public class CalculatorClient { public static void main(String[] argv)throws Exception { String endpoint = "http://localhost:80/axis/SimpleCalculator.jws"; Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("add"); Object value = call.invoke(new Object[] {new Integer(4), new Integer(6)}); System.out.println(value); }}
How does it Work?How does it Work?
• On the first time the jws file is being called, it is compiled into a class- WEB-INF/jwsClasses/SimpleCalculator.class
• Axis then considers the URL of the jws as one of a regular web service- Default configurations are assumed
• Sounds like any other technology we know?
When not to Use jws Files 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
Axis Type MappingsAxis Type Mappings
Axis Type MappingsAxis Type Mappings
• Axis uses mappings between SOAP types and Java classes and primitive types- In client side: SOAP → Java
- In server side: Java → SOAP
• Serialization and deserialization are executed by objects of the interfaces Serializer and Deserializer (provided by Axis), respectively- For example, SimpleSerializer, SimpleDeserializer,
DateDeserializer, ArraySerializer
Axis Type Mapping
Complex Type Example - Service SideComplex Type Example - Service Sidepackage myws;import java.util.*;public class VectorService { public Vector getAsVector(int[] array) { Vector result = new Vector(); for(int i=0; i<array.length; ++i) result.add("Number " + array[i]); return result; }} VectorService.java
<service name="tovector" provider="java:RPC"> <parameter name="className" value="myws.VectorService"/> <parameter name="scope" value="application"/> <parameter name="allowedMethods" value="getAsVector"/></service> services.wsdd
Input in The WSDLInput in The WSDL
<complexType name="ArrayOf_xsd_int"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[]"/> </restriction> </complexContent></complexType>
<wsdl:message name="getAsVectorRequest"> <wsdl:part name="array" type="impl:ArrayOf_xsd_int"/></wsdl:message>
Output in The WSDLOutput in The WSDL
<complexType name="Vector"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="xsd:anyType"/> </sequence></complexType>
<wsdl:message name="getAsVectorResponse" <wsdl:part name="getAsVectorReturn" type="apachesoap:Vector"/></wsdl:message>
Complex Type Example - Client SideComplex Type Example - Client Side
import java.util.*;import org.apache.axis.client.*;public class VectorClient { public static void main(String[] argv)throws Exception { String endpoint = "http://localhost/axis/services/tovector"; Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("getAsVector"); int[] array = {3,7}; Vector value =
(Vector)call.invoke(new Object[] {array}); printVector(value);}
VectorClient.java
A Snapshot from the RequestA Snapshot from the Request
<getAsVector soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<arg0 xsi:type="soapenc:Array" soapenc:arrayType="xsd:int[2]" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<item>3</item> <item>7</item> </arg0></getAsVector>
A Snapshot from the ResponseA Snapshot from the Response
<getAsVectorResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getAsVectorReturn href="#id0"/></getAsVectorResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns1:Vector" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://xml.apache.org/xml-soap">
<item xsi:type="soapenc:string">Number 3</item> <item xsi:type="soapenc:string">Number7</item> </multiRef>
Java BeansJava Beans
• Java Beans are simply objects of classes that follow some (natural) coding conventions:- An empty constructor
- A readable property has a matching getter
- A writable property has a matching setter
• A property has name and a type
• The getter of property prop: type getProp()
• The setter of property prop: void setProp()
An ExampleAn Example
package myws;public class Person { private String firstName, lastName; private int personID;
public String getFirstName() {return firstName;} public void setFirstName(String firstName) { this.firstName = firstName;} public String getLastName() {return lastName;} public void setLastName(String lastName) { this.lastName = lastName; } public void setId(int id) {personID = id;} public int getId(int id) {return personID;}}
property firstName
Property lastName
Property id
Using Beans in Web ServicesUsing Beans in Web Services
• A Web service can use beans in its definition- either in its input or output
• For that, you need to tell the Axis engine that the corresponding object needs to be serialized as a bean
• In this serialization, every readable property (i.e., one that has a getter) is specified
• Where, in the file system, should the bean class reside?
A Service ExampleA Service Example
package myws; public class PersonService { public Person createPerson() { Person person = new Person(); person.setFirstName("f"); person.setLastName("l"); person.setId(2); return person; }}
The WSDLThe WSDL
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="person" provider="java:RPC"> <parameter name="className" value="myws.PersonService"/> <parameter name="scope" value="application"/> <parameter name="allowedMethods" value="*"/> <beanMapping qname="ns:person" xmlns:ns="http://www.cs.huji.ac.il/~dbi/xsd"
languageSpecificType="java:myws.Person"/> </service></deployment>
Using Beans in ClientsUsing Beans in Clients
• To use a bean on the client side, you need to configure service to deserialize the SOAP type into a Java bean
• For that, we use the class BeanSerializer provided by Axis
• Note that client and server beans need not be the class- What should they have in common?
public class PersonClient { public static void main(String[] argv) throws Exception {
String endpoint = "http://localhost/axis/services/person"; Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("createPerson"); QName qn = new QName("http://www.cs.huji.ac.il/~dbi/xsd", "person"); BeanDeserializerFactory bdf = new BeanDeserializerFactory(MyPerson.class,qn); call.registerTypeMapping(MyPerson.class, qn, null, bdf); MyPerson value = (MyPerson)call.invoke(new Object[] {}); System.out.println(value); }}
Identical to Person
Exception HandlingException Handling
Exception in Service CallsException in Service Calls
• Several problems can cause exception to be thrown when a service is being invoked
• For example- the server cannot be connected
- the server does not find the requested URL
- the request is inappropriate (no such operation, invalid arguments, etc.)
- the implementing service method has thrown an exception
Service ExceptionService Exception
• When the implementing service throws an exception, a SOAP fault response is returned by the server
• The client invocation method translates this response to a java.rmi.RemoteException after parsing the response
An ExampleAn Example
package myws; public class ExceptionService { public void throwException() throws IllegalStateException { throw new IllegalStateException ("I only throw an exception!");}}
<service name="exception" provider="java:RPC"> <parameter name="className" value="myws.ExceptionService"/> <parameter name="allowedMethods" value="*"/></service> services.wsddservices.wsdd
public class ExceptionClient { public static void main(String[] argv){ String endpoint = "http://localhost:80/axis/services/exception"; try { Call call = (Call) new Service().createCall(); call.setTargetEndpointAddress(endpoint); call.setOperationName("throwException"); Object value = call.invoke(new Object[] {}); System.out.println(value); } catch(RemoteException exp) { System.err.println("WS invocation error: " + exp.getMessage()); }catch(Exception exp) {System.err.println("Error: " + exp.getMessage());}}}
A Snapshot from the ResponseA Snapshot from the Response
<soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>java.lang.IllegalStateException: I only throw an exception!</faultstring> <detail>...</detail> </soapenv:Fault></soapenv:Body>
Sharing Information with Sharing Information with Web ApplicationsWeb Applications
The ScenarioThe Scenario
• In your project, you will have two Web applications under Tomcat 5.0:- Your Web site
- Axis application for publishing Web services
• The above two applications need to share information- e.g., the database connection parameters
• How will your Web application pass that information to the service method?
A Possible SolutionA Possible Solution
• Tomcat uses one class loader for all classes under $CATALINA_BASE/share/
• Hence, a static variable in one of those classes will be accessible to every class running under Tomcat
A Possible SolutionA Possible Solution
$CATALINA_BASE
webapps shared
myapplication axis lib classes
SharedClass1. Put the the shared class under shared
2. Use a static field of the shared class to hold the shared object
3. The first time a you discover the parameter, store it the shared class