Transcript ppt
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
A request to
<?xml version="1.0" encoding="UTF-8"?>
www.jusufdarmawan.com
<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>
HTTP/1.0 200 OK
Date: Mon, 09 May 2005 20:58:35 GMT
Content-Length: 619
Content-Type: text/xml
Server: Microsoft-IIS/5.0
X-Powered-By: ASP.NET
<?xml version="1.0" encoding='UTF-8'?>
The Response
<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>
POST /soap HTTP/1.0
SOAPAction: ""
Content-Length: 520
A request to
services.xmethods.net
<?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>
HTTP/1.0 200 OK
Date: Sat, 07 May 2005 23:26:21 GMT
Content-Length: 492
The Response
Content-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>
<?xml version="1.0"?>
<definitions name="CurrencyExchangeService"
A WSDL Example
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>
<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 Elements
Service
*
Port
Binding
Input
Output
Operation
*
Port Type
Apache EXtensible
Interaction System
(Axis)
What is AXIS
• Axis is essentially a SOAP engine – a framework
for constructing SOAP processors
- client side
- server side
• Axis implements the interfaces of JAX-RPC
(XML-based remote procedure calls in Java)
• AXIS = Apache EXtensible Interaction System
Apache AXIS: Included Tools
• A simple stand-alone server
• A Web application that resides in Servlet engines, such
as Tomcat
• Standalone tools for Web-service invocation
- Java/C components
• Extensive support for the Web Service Description
Language (WSDL)
- E.g., tools for generating Java classes (stubs) from WSDL and
vice versa
• … and more
Remote Method Invocation is not New
• 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
What 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 Applications
Calling 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
- This is the whole point of using standards…
Invoking 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 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
Example: Currency Exchange
import org.apache.axis.client.*;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.encoding.XMLType;
public class CurrencyExchange {
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 Exchange
(cont)
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);
}
}
Using 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)
• When there is only one port, we can obtain it
automatically
• 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 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";
QName sName = new
QName("http://www.xmethods.net/sd/CurrencyExchangeService.wsdl",
"CurrencyExchangeService");
String oName = "getRate";
Service service = new Service(wsdl, sName);
QName port = (QName)service.getPorts().next();
Call call = (Call)service.createCall(port, oName);
System.out.println(call.invoke(new Object[] {"UK","Israel"}));
}}
public class PrimeNumbers {
public static void main(String[] args) throws Exception {
System.setProperty("http.proxyHost",“wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort","8080");
String wsdl = "http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl";
QName sName = new
QName("http://www50.brinkster.com/vbfacileinpt/np","pnum");
String oName = "GetPrimeNumbers";
Service service = new Service(wsdl, sName);
QName port = (QName)service.getPorts().next();
Call call = (Call)service.createCall(port, oName);
System.out.println(call.invoke(new Object[] {100}));
}}
The 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
Generated 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
An Example
Using The Generated Classes
import com.brinkster.www50.vbfacileinpt.np.*;
public class PrimeNumbers2 {
public static void main(String[] args) throws Exception {
System.setProperty("http.proxyHost","wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort","8080");
PnumSoap ps = new PnumLocator().getpnumSoap();
System.out.println(ps.getPrimeNumbers("20"));
}
}
Server Applications
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 are in $CATALINA_HOME/lib/
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
$CATALINA_HOME
webapps
lib
myapplication
axis
The directory that
you need to copy
axis.jar
saaj.jar
Classes were
added for you
…
Creating 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 Class
package myws;
public class Power {
public int power(int a, int n) {
return (int)Math.pow(a,n);
}
}
$CATALINA_BASE/webapps/axis/WEB-INF/
classes/myws/Power.class
2. Deploy the Service using Web
Service 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.wsdd
java org.apache.axis.client.AdminClient
-hlocalhost -p8080 services.wsdd
That's it! You Can Call the Service.
import org.apache.axis.client.*;
public class PowerClient {
public static void main(String[] argv)throws Exception {
String endpoint =
"http://mangal:8080/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?
• 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)
• 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 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.wsdd
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
Undeploying a Service
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="mypower"/>
undeploy.wsdd
</undeployment>
java org.apache.axis.client.AdminClient
-hlocalhost -p8080 undeploy.wsdd
Implementing Classes
• The class that implements the Web service must
be accessible to the Axis Servlet
• Hence, this class should reside in a package in
$CATALINA_BASE/webapps/axis/WEB-INF/classes/
• Of course, all helper classes should be accessible
to the Axis application too
The 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:8080/axis/services/mypower?wsdl
Power-Service WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://inferno-02/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>
<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://inferno-02:8080/axis/services/mypower"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
jws 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/ (the
application’s root)
4. That is all. Now you can call the service!
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;
}
}
$CATALINA_BASE/webapps/axis/SimpleCalculator.jws
Service URL:
http://server:port/axis/SimpleCalculator.jws
Example: a Calculator Service
public class CalculatorClient {
public static void main(String[] argv)throws Exception {
String endpoint =
"http://localhost:8080/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?
• 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 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 Mappings
Axis Type Mappings
• Axis uses mappings between SOAP types and Java
classes and primitive types
• 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 Side
package 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 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 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 Side
import java.util.*;
import org.apache.axis.client.*;
public class VectorClient {
public static void main(String[] argv)throws Exception {
String endpoint = "http://localhost:7000/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 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 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">Number 7</item>
</multiRef>
Java 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(type)
An Example
package myws;
public class Person {
private String firstName, lastName;
private int personID;
property firstName
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;
Property lastName
}
public void setId(int id) {personID = id;}
public int getId(int id) {return personID;}
}
Property id
Using 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 accessible property
(i.e., one that has a getter/setter) is specified
• Where, in the file system, should the bean class
reside?
A 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 WSDD
<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 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 BeanDeserializer
provided by Axis
• Note that client and server beans need not be the
same 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 =
Identical to
new QName("http://www.cs.huji.ac.il/~dbi/xsd",
"person");
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);
}
}
Exception Handling
Exception 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 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 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.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 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>