Download as pdf or txt
Download as pdf or txt
You are on page 1of 12

Handling Web Services

Web-Service Review
with Apache AXIS
By Examples ...

POST /wsprimegenerator.exe/soap/IPrimeGenerator HTTP/1.0 HTTP/1.0 200 OK


Content-Type: text/xml; charset=utf-8 Date: Mon, 09 May 2005 20:58:35 GMT
Host: www.jusufdarmawan.com Content-Length: 619
SOAPAction: "urn:UnitIPrimeGenerator-IPrimeGenerator#primegenerator" Content-Type: text/xml
Content-Length: 527 Server: Microsoft-IIS/5.0
A request to X-Powered-By: ASP.NET
<?xml version="1.0" encoding="UTF-8"?> www.jusufdarmawan.com The Response
<?xml version="1.0" encoding='UTF-8'?>
<soapenv:Envelope <SOAP-ENV:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<soapenv:Body> xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:primegenerator
<NS1:primegeneratorResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:UnitIPrimeGenerator-IPrimeGenerator"
xmlns:ns1="urn:UnitIPrimeGenerator-IPrimeGenerator"> SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<valstart xsi:type="xsd:string">12</valstart> <return xsi:type="xsd:string">13,17,19,23,29,31, 37, 41,43, 47,
<valend xsi:type="xsd:string">120</valend> 53,59,61,67,71,73,79,83,89,97,101,103,107,109,113</return>
</ns1:primegenerator> </NS1:primegeneratorResponse>
</soapenv:Body> </SOAP-ENV:Body>
</soapenv:Envelope> </SOAP-ENV:Envelope>

HTTP/1.0 200 OK
POST /soap HTTP/1.0
A request to Date: Sat, 07 May 2005 23:26:21 GMT
SOAPAction: ""
services.xmethods.net Content-Length: 492
Content-Length: 520
Content-Type: text/xml The Response
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" <soap:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
<soapenv:Body> xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
<ns1:getRate soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" <soap:Body>
xmlns:ns1="urn:xmethods-CurrencyExchange"> <n:getRateResponse
<country1 xsi:type="xsd:string">Euro</country1> xmlns:n='urn:xmethods-CurrencyExchange'>
<country2 xsi:type="xsd:string">Israel</country2> <Result xsi:type='xsd:float'>5.5825</Result>
</ns1:getRate> </n:getRateResponse>
</soapenv:Body> </soap:Body>
</soapenv:Envelope> </soap:Envelope>

1
<?xml version="1.0"?>
A WSDL Example <binding name="CurrencyExchangeBinding" type="tns:CurrencyExchangePortType">
<definitions name="CurrencyExchangeService" <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
targetNamespace="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl" <operation name="getRate">
xmlns:tns="http://www.xmethods.net/sd/CurrencyExchangeService.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" <soap:operation soapAction=""/>
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" <input name="getRate">
xmlns="http://schemas.xmlsoap.org/wsdl/">
<soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
<message name="getRateRequest"> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<part name="country1" type="xsd:string"/> </input>
<part name="country2" type="xsd:string"/> <output name="getRateResponse">
</message> <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
<message name="getRateResponse"> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
<part name="Result" type="xsd:float"/> </operation>
</message> </binding>
<portType name="CurrencyExchangePortType"> <service name="CurrencyExchangeService">
<documentation>Returns the exchange rate between the two currencies</documentation>
<operation name="getRate">
<port name="CurrencyExchangePort" binding="tns:CurrencyExchangeBinding">
<input message="tns:getRateRequest" name="getRate"/> <soap:address location="http://services.xmethods.net:80/soap"/>
<output message="tns:getRateResponse" </port>
name="getRateResponse"/> </service>
</operation></portType> </definitions>

WSDL Elements

Service * Port Apache EXtensible


Interaction System
Binding
(Axis)
Input Output

Operation * Port Type

What is AXIS Apache AXIS: Included Tools


• Axis is essentially a SOAP engine – a framework • A simple stand-alone server
for constructing SOAP processors • A Web application that resides in Servlet engines, such
- client side as Tomcat
• Standalone tools for Web-service invocation
- server side
- Java/C components
• Axis implements the interfaces of JAX-RPC
• Extensive support for the Web Service Description
(XML-based remote procedure calls in Java) Language (WSDL)
• AXIS = Apache EXtensible Interaction System - E.g., tools for generating Java classes (stubs) from WSDL and
vice versa
• … and more

2
Remote Method Invocation is not New What We Would Like to Create
• java.rmi has been in Java since Java’s early versions • Client applications: applications that can call a
• In Java RMI, objects can invoke methods of objects that remote Web service
reside on a remote computer
• Services: methods that can be called by remote
- (RMI = Remote Method Invocation)
applications
• So, what has been changed?
• Service descriptions: WSDL files that describe
- Using HTTP for communication
- Using agreed protocols, Java can invoke methods that were
our methods
not written in Java (e.g., .NET methods) and vice versa
- A complex registry procedure has been required in RMI

Calling Web Services

• By now, we already know how to invoke a


remote Web service in Java:
Client Applications - 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 Invoking Services with Axis

• Axis includes comfortable tools for managing • To invoke an operation of a Web service, do the
calls to Web services following:
• The programmer configures the request for the - Construct a Service instance
Web service using a friendly API - Using the Service instance, generate a Call instance
- with, or without considering the WSDL - Configure the Call instance
• According to the configuration, a method - Invoke the call
invocation is transformed into a SOAP request
that is sent to the remote server

3
Example: Currency Exchange Example: Currency Exchange
import org.apache.axis.client.*; (cont)
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode; call.setTargetEndpointAddress(endpointUrl);
import javax.xml.rpc.encoding.XMLType; call.setOperationName(new QName(nsuri,"getRate"));
call.addParameter("country1", XMLType.SOAP_STRING,
public class CurrencyExchange { ParameterMode.IN);
call.addParameter("country2", XMLType.SOAP_STRING,
ParameterMode.IN);
public static void main(String[] args) throws Exception {
System.setProperty("http.proxyHost","wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort","8080"); call.setReturnType(XMLType.SOAP_FLOAT);

Object ret = call.invoke(new Object[] {"Euro","Israel"});


String endpointUrl = "http://services.xmethods.net:80/soap";
String nsuri = "urn:xmethods-CurrencyExchange";
System.out.println(ret);
Service service = new Service(); }
}
Call call = (Call) service.createCall();

public class CurrencyExchange2 {


public static void main(String[] args) throws Exception {
Using the WSDL System.setProperty("http.proxyHost",“wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort","8080");
• Axis can read a given WSDL and configure the service
as much as possible from that WSDL String wsdl = "http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl";
• Instead of using the default constructor, construct the QName sName = new
service using the following constructor: QName("http://www.xmethods.net/sd/CurrencyExchangeService.wsdl",
"CurrencyExchangeService");
Service(String wsdlLocation, QName serviceName)
String oName = "getRate";
• When there is only one port, we can obtain it
automatically Service service = new Service(wsdl, sName);
• In this approach, you usually need to know the QName port = (QName)service.getPorts().next();
following about the service: Call call = (Call)service.createCall(port, oName);
- the WSDL URL, the service name, the namespace uri, the System.out.println(call.invoke(new Object[] {"UK","Israel"}));
operation name and the expected arguments
}}

public class PrimeNumbers { The WSDL2Java Application


public static void main(String[] args) throws Exception {
System.setProperty("http.proxyHost",“wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort","8080"); • Axis provides a mechanism for communicating
with a Web service using stubs
String wsdl = "http://www50.brinkster.com/vbfacileinpt/np.asmx?wsdl";
QName sName = new • That is, generation of regular Java classes that
QName("http://www50.brinkster.com/vbfacileinpt/np","pnum"); have an interface similar to that of the Web
String oName = "GetPrimeNumbers";
service and implementation that wraps Web
Service service = new Service(wsdl, sName); service management
QName port = (QName)service.getPorts().next();
Call call = (Call)service.createCall(port, oName);
• Invoke class WSDL2Java in order to create the
required Java classes
System.out.println(call.invoke(new Object[] {100}));
}}

4
Generated Classes An Example

• 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

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");
Server Applications
System.setProperty("http.proxyPort","8080");

PnumSoap ps = new PnumLocator().getpnumSoap();

System.out.println(ps.getPrimeNumbers("20"));
}
}

AXIS Installation AXIS Installation (cont)


• Axis works inside a Servlet container (e.g., Tomcat) • You need to copy the Axis application to your
• You should add to your Tomcat libs some jar files: Tomcat's application directory:
axis.jar, saaj.jar, wsdl4j.jar, … cp -r ~dbi/tomcat/axis/ $CATALINA_BASE/webapps
• You need to include several jar files in your
$CATALINA_BASE $CATALINA_HOME
CLASSPATH
• This has already been done for you!
webapps lib
- The needed CLASSPATH definitions where added to
dbi.cshrc
- The needed jar files are in $CATALINA_HOME/lib/ myapplication axis axis.jar saaj.jar …
The directory that Classes were
you need to copy added for you

5
Creating a Web Service 1. Generate the Implementing Class

Next, we will see how we can create and publish


a Web service using the Axis plugin in Tomcat 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


That's it! You Can Call the Service.
Service Deployment Descriptor
import org.apache.axis.client.*;
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> public class PowerClient {

<service name="mypower" provider="java:RPC"> public static void main(String[] argv)throws Exception {


<parameter name="className" value="myws.Power"/> String endpoint =
<parameter name="scope" value="application"/> "http://mangal:8080/axis/services/mypower";
<parameter name="allowedMethods" value="*"/> Call call = (Call) new Service().createCall();
</service> call.setTargetEndpointAddress(endpoint);
call.setOperationName("power");
</deployment> services.wsdd Object value = call.invoke(new Object[]
{new Integer(2), new Integer(5)});
java org.apache.axis.client.AdminClient System.out.println(2+"^"+5 +"=" + value);
-hlocalhost -p8080 services.wsdd }
}

How Does it Work? How Does it Work? (cont)

• The AXIS plugin is simply a Web application • The wsdd file defines mappings between a Web
that resides in Tomcat (under webapps/) service elements to a Java class elements
• The Servlet AxisServlet of this application is - I.e., names, methods, etc.
responsible for invoking services • The class AdminClient sends a request to the
• All URLs of the form /services/* are mapped to application to register the service based on the
the AxisServlet wsdd content
- Where is that written? • When a SOAP request arrives, the AxisServlet
object parses the request and invokes the
corresponding method of the class associated
with the service URL

6
The Deployment Descriptor The Scope of the Object

<deployment xmlns="http://xml.apache.org/axis/wsdd/" • Request (the default): a new object is created for each
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> request, the service instance is available for the duration
of the request (regardless of forwarding)
<service name="mypower" provider="java:RPC">
<parameter name="className" value="myws.Power"/> • Session: a new object is created for each new session
<parameter name="scope" value="application"/> and the service instance is available for the entire
<parameter name="allowedMethods" value="*"/> session
</service>
• Application: a singleton shared service instance is used
</deployment> services.wsdd to serve all invocations

Undeploying a Service Implementing Classes

• The class that implements the Web service must


be accessible to the Axis Servlet
<undeployment xmlns="http://xml.apache.org/axis/wsdd/"> • Hence, this class should reside in a package in
<service name="mypower"/>
</undeployment> undeploy.wsdd $CATALINA_BASE/webapps/axis/WEB-INF/classes/

java org.apache.axis.client.AdminClient
• Of course, all helper classes should be accessible
-hlocalhost -p8080 undeploy.wsdd to the Axis application too

Power-Service WSDL
The Service WSDL <?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://inferno-02/axis/services/mypower"
xmlns="http://schemas.xmlsoap.org/wsdl/"
• Axis automatically provides a WSDL for each xmlns:apachesoap="http://xml.apache.org/xml-soap"
deployed service xmlns:impl="http://localhost/axis/services/mypower"
xmlns:intf="http://localhost/axis/services/mypower"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
• To get the WSDL, use the service URL with the xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
empty argument wsdl xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
http://localhost:8080/axis/services/mypower?wsdl <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>

7
<wsdl:binding name="mypowerSoapBinding" type="impl:Power">
<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="power">
<wsdl:portType name="Power"> <wsdlsoap:operation soapAction=""/>
<wsdl:operation name="power" parameterOrder="a n"> <wsdl:input name="powerRequest">
<wsdl:input message="impl:powerRequest" <wsdlsoap:body
name="powerRequest"/> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://myws" use="encoded"/>
<wsdl:output message="impl:powerResponse"
</wsdl:input>
name="powerResponse"/>
<wsdl:output name="powerResponse">
</wsdl:operation>
<wsdlsoap:body
</wsdl:portType> encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://localhost/axis/services/mypower" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

jws Files

<wsdl:service name="PowerService"> • There is a fast and easy way of crating a service:


<wsdl:port binding="impl:mypowerSoapBinding" 1. Create a Java class myClass.java
name="mypower">
<wsdlsoap:address 2. Rename your class to end with jws: myClass.jws
location="http://inferno-02:8080/axis/services/mypower"/> 3. Put the jws file directly under the directory
</wsdl:port> $CATALINA_BASE/webapps/axis/ (the
</wsdl:service>
</wsdl:definitions>
application’s root)
4. That is all. Now you can call the service!

Example: a Calculator Service Example: a Calculator Service


public class SimpleCalculator { public class CalculatorClient {
public static void main(String[] argv)throws Exception {
public int add(int i1, int i2) {
return i1 + i2; String endpoint =
} "http://localhost:8080/axis/SimpleCalculator.jws";
public int subtract(int i1, int i2) { Call call = (Call) new Service().createCall();
return i1 - i2; call.setTargetEndpointAddress(endpoint);
} call.setOperationName("add");
} Object value = call.invoke(new Object[] {new
Integer(4), new Integer(6)});
$CATALINA_BASE/webapps/axis/SimpleCalculator.jws System.out.println(value);
Service URL: }
}
http://server:port/axis/SimpleCalculator.jws

8
How does it Work? When not to Use jws Files

• On the first time the jws file is being called, it is • When you do not have the Java source code
compiled into a class • When you don’t want to expose your code
- WEB-INF/jwsClasses/SimpleCalculator.class • When you want to use custom type mappings
• Axis then considers the URL of the jws as one of • When you want to use other configuration
a regular web service options
- Default configurations are assumed
• Sounds like any other technology we know?

Axis Type Mappings


• Axis uses mappings between SOAP types and Java
classes and primitive types
• Serialization and deserialization are executed by objects
Axis Type Mappings of the interfaces Serializer and Deserializer (provided
by Axis), respectively
- For example, SimpleSerializer, SimpleDeserializer,
DateDeserializer, ArraySerializer

Axis Type Mapping

Complex Type Example - Service Side Input in The WSDL


package myws;
import java.util.*; <complexType name="ArrayOf_xsd_int">
<complexContent>
public class VectorService {
<restriction base="soapenc:Array">
public Vector getAsVector(int[] array) { <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[]"/>
Vector result = new Vector(); </restriction>
for(int i=0; i<array.length; ++i) </complexContent>
result.add("Number " + array[i]); </complexType>
return result;
} <wsdl:message name="getAsVectorRequest">
} <wsdl:part name="array" type="impl:ArrayOf_xsd_int"/>
VectorService.java </wsdl:message>
<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

9
Output in The WSDL Complex Type Example - Client Side

<complexType name="Vector"> import java.util.*;


<sequence> import org.apache.axis.client.*;
<element maxOccurs="unbounded" minOccurs="0" public class VectorClient {
name="item" type="xsd:anyType"/> public static void main(String[] argv)throws Exception {
</sequence> String endpoint = "http://localhost:7000/axis/services/tovector";
</complexType> Call call = (Call) new Service().createCall();
call.setTargetEndpointAddress(endpoint);
<wsdl:message name="getAsVectorResponse" call.setOperationName("getAsVector");
<wsdl:part name="getAsVectorReturn" int[] array = {3,7};
type="apachesoap:Vector"/> Vector value =
</wsdl:message> (Vector)call.invoke(new Object[] {array});
printVector(value);
} VectorClient.java

A Snapshot from the Request A Snapshot from the Response


<getAsVectorResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getAsVector
<getAsVectorReturn href="#id0"/>
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
</getAsVectorResponse>
<arg0 xsi:type="soapenc:Array"
soapenc:arrayType="xsd:int[2]"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> <multiRef id="id0" soapenc:root="0"
<item>3</item> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
<item>7</item> xsi:type="ns1:Vector"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
</arg0> xmlns:ns1="http://xml.apache.org/xml-soap">
</getAsVector> <item xsi:type="soapenc:string">Number 3</item>
<item xsi:type="soapenc:string">Number 7</item>
</multiRef>

An Example
Java Beans
package myws;
public class Person {
• Java Beans are simply objects of classes that private String firstName, lastName;
follow some (natural) coding conventions: private int personID;
property firstName
- An empty constructor public String getFirstName() {return firstName;}
- A readable property has a matching getter public void setFirstName(String firstName) {
this.firstName = firstName;}
- A writable property has a matching setter public String getLastName() {return lastName;}
• A property has name and a type public void setLastName(String lastName) {
this.lastName = lastName;
• The getter of property prop: type getProp() } Property lastName
public void setId(int id) {personID = id;}
• The setter of property prop: void setProp(type) public int getId(int id) {return personID;}
} Property id

10
Using Beans in Web Services A Service Example

• A Web service can use beans in its definition


- either in its input or output package myws;
public class PersonService {
• For that, you need to tell the Axis engine that the public Person createPerson() {
Person person = new Person();
corresponding object needs to be serialized as a
person.setFirstName("f");
bean person.setLastName("l");
person.setId(2);
• In this serialization, every accessible property return person;
(i.e., one that has a getter/setter) is specified }
}
• Where, in the file system, should the bean class
reside?

The WSDD Using Beans in Clients


<deployment xmlns="http://xml.apache.org/axis/wsdd/" • To use a bean on the client side, you need to
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="person" provider="java:RPC"> configure service to deserialize the SOAP type
<parameter name="className" into a Java bean
value="myws.PersonService"/>
<parameter name="scope" value="application"/> • For that, we use the class BeanDeserializer
<parameter name="allowedMethods" value="*"/> provided by Axis
<beanMapping qname="ns:person"
xmlns:ns="http://www.cs.huji.ac.il/~dbi/xsd" • Note that client and server beans need not be the
languageSpecificType="java:myws.Person"/> same class
</service>
</deployment> - 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 =
Exception Handling
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);
}
}

11
Exception in Service Calls Service Exception

• Several problems can cause exception to be • When the implementing service throws an
thrown when a service is being invoked exception, a SOAP fault response is returned by
• For example the server
- the server cannot be connected • The client invocation method translates this
- the server does not find the requested URL response to a java.rmi.RemoteException after
parsing the response
- the request is inappropriate (no such operation,
invalid arguments, etc.)
- the implementing service method has thrown an
exception

public class ExceptionClient {


An Example public static void main(String[] argv){
String endpoint = "http://localhost:80/axis/services/exception";
package myws; try {
public class ExceptionService { Call call = (Call) new Service().createCall();
public void throwException() throws IllegalStateException { call.setTargetEndpointAddress(endpoint);
throw new IllegalStateException call.setOperationName("throwException");
("I only throw an exception!"); Object value = call.invoke(new Object[] {});
}} System.out.println(value);
<service name="exception" provider="java:RPC"> }
<parameter name="className" catch(RemoteException exp) {
value="myws.ExceptionService"/> System.err.println("WS invocation error: " +
<parameter name="allowedMethods" value="*"/> exp.getMessage());
</service> }
services.wsdd 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>

12

You might also like