Webservices - Axis: 1.1. Table of Contents
Webservices - Axis: 1.1. Table of Contents
Page 1
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.2. Introduction
Welcome to Axis, the third generation of Apache SOAP!
Page 2
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
After months of continued discussion and coding effort in this direction, Axis now delivers
the following key features:
• Speed. Axis uses SAX (event-based) parsing to acheive significantly greater speed than
earlier versions of Apache SOAP.
• Flexibility. The Axis architecture gives the developer complete freedom to insert
extensions into the engine for custom header processing, system management, or
anything else you can imagine.
• Stability. Axis defines a set of published interfaces which change relatively slowly
compared to the rest of Axis.
• Component-oriented deployment. You can easily define reusable networks of Handlers to
implement common patterns of processing for your applications, or to distribute to
partners.
• Transport framework. We have a clean and simple abstraction for designing transports
(i.e., senders and listeners for SOAP over various protocols such as SMTP, FTP,
message-oriented middleware, etc), and the core of the engine is completely
transport-independent.
• WSDL support. Axis supports the Web Service Description Language, version 1.1, which
allows you to easily build stubs to access remote services, and also to automatically
export machine-readable descriptions of your deployed services from Axis.
We hope you enjoy using Axis. Please note that this is an open-source effort - if you feel the
code could use some new features or fixes, please get involved and lend a hand! The Axis
developer community welcomes your participation. And in case you're wondering what Axis
stands for, it's Apache EXtensible Interaction System - a fancy way of implying it's a very
configurable SOAP engine.
Let us know what you think!
Please send feedback about the package to "[email protected]". Also, Axis is
registered in jira, the Apache bug tracking and feature-request database.
Page 3
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
Page 4
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
Page 5
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
<SOAP-ENV:Body>
<ns1:echoString xmlns:ns1="http://soapinterop.org/">
<arg0 xsi:type="xsd:string">Hello!</arg0>
</ns1:echoString>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The String argument is automatically serialized into XML, and the server responds with an
identical String, which we deserialize and print.
Note: To actually watch the XML flowing back and forth between a SOAP client and server,
you can use the included tcpmon tool or SOAP monitor tool. See the appendix for an
overview.
Page 6
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
this happens, which sheds light on a potential problem (to which, of course, we have a
solution - so don't fret :)).
Here's what a typical response might look like to the echoString method:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
<result xsi:type="xsd:string">Hello!</result>
</ns1:echoStringResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Take a look at the section which we've highlighted in red - that attribute is a schema type
declaration, which Axis uses to figure out that the contents of that element are, in this case,
deserializable into a Java String object. Many toolkits put this kind of explicit typing
information in the XML to make the message "self-describing". On the other hand, some
toolkits return responses that look like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
<result>Hello, I'm a string!</result>
</ns1:echoStringResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
There's no type in the message, so how do we know what Java object we should deserialize
the <result> element into? The answer is metadata - data about data. In this case, we need a
description of the service that tells us what to expect as the return type. Here's how to do it on
the client side in Axis:
call.setReturnType( org.apache.axis.Constants.XSD_STRING );
This method will tell the Axis client that if the return element is not typed then it should act
as if the return value has an xsi:type attribute set to the predefined SOAP String type. (You
can see an example of this in action in the interop echo-test client -
samples/echo/TestClient.java.)
There is also a similar method which allows you to specify the Java class of the expected
return type:
call.setReturnClass(String.class);
Page 7
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
OK - so now you know the basics of accessing SOAP services as a client. But how do you
publish your own services?
Page 8
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
after deployment. Production quality web services should use Java classes with custom
deployment.
Page 9
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
could also have restricted the SOAP-accessible methods by using a space or comma
separated list of available method names).
Page 10
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
server:
% java org.apache.axis.client.AdminClient list
<big XML document returned here>
In there you'll see services, handlers, transports, etc. Note that this listing is an exact copy of
the server's "server-config.wsdd" file, which we'll talk about in more detail a little later.
Page 11
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
set the "enableRemoteAdmin" property of the AdminService to true. To do this, find the
"server-config.wsdd" file in your webapp's WEB-INF directory. In it, you'll see a deployment
for the AdminService. Add an option as follows:
<service name="AdminService" provider="java:MSG">
<parameter name="className" value="org.apache.axis.util.Admin"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="enableRemoteAdmin" value="true"/>
</service>
WARNING: enabling remote administration may give unauthorized parties access to your
machine. If you do this, please make sure to add security to your configuration!
Page 12
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
A good place to start in describing the difference between document and wrapped services is
with a sample SOAP message containing a purchase order:
<soap:Envelope xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<soap:Body>
<myNS:PurchaseOrder xmlns:myNS="http://commerce.com/PO">
<item>SK001</item>
<quantity>1</quantity>
<description>Sushi Knife</description>
</myNS:PurchaseOrder>
</soap:Body>
</soap:Envelope>
The relevant schema for the PurchaseOrder looks like this:
<schema targetNamespace="http://commerce.com/PO">
<complexType name="POType">
<sequence>
<element name="item" type="xsd:string"/>
<element name="quantity" type="xsd:int"/>
<element name="description" type="xsd:string"/>
</sequence>
</complexType>
<element name="PurchaseOrder" type="POType"/>
</schema>
For a document style service, this would map to a method like this:
public void method(PurchaseOrder po)
In other words, the ENTIRE <PurchaseOrder> element would be handed to your method as a
single bean with three fields inside it. On the other hand, for a wrapped style service, it would
map to a method like this:
public void purchaseOrder(String item, int quantity, String
description)
Note that in the "wrapped" case, the <PurchaseOrder> element is a "wrapper" (hence the
name) which only serves to indicate the correct operation. The arguments to our method are
what we find when we "unwrap" the outer element and take each of the inner ones as a
parameter.
The document or wrapped style is indicated in WSDD as follows:
<service ... style="document"> for document style
<service ... style="wrapped"> for wrapped style
In most cases you won't need to worry about document or wrapped services if you are
starting from a WSDL document (see below).
Page 13
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
Page 14
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
xsd:boolean boolean
xsd:byte byte
xsd:dateTime java.util.Calendar
xsd:decimal java.math.BigDecimal
xsd:double double
xsd:float float
xsd:hexBinary byte[]
xsd:int int
xsd:integer java.math.BigInteger
xsd:long long
Page 15
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
xsd:QName javax.xml.namespace.QName
xsd:short short
xsd:string java.lang.String
If the WSDL says that an object can be nillable, that is the caller may choose to return a
value of nil, then the primitive data types are replaced by their wrapper classes, such as
Byte, Double, Boolean, etc.
1.6.2. Exceptions
This is an area which causes plenty of confusion, and indeed, the author of this section is not
entirely sure how everything works, especially from an interop perspective. This means treat
this section as incomplete and potentially inaccurate. See also section 5.5.5 and chapter 14 in
the JAX-RPC specification
Page 16
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
longer a SOAP Fault, but described as a wsdl:fault in the WSDL of the method.
According to the JAX-RPC specification, your subclass of Exception must have accessor
methods to access all the fields in the object to be marshalled and a constructor that takes as
parameters all the same fields (i.e, arguments of the same name and type). This is a kind of
immutable variant of a normal JavaBean. The fields in the object must be of the datatypes
that can be reliably mapped into WSDL.
If your exception meets this specification, then the WSDL describing the method will
describe the exception too, enabling callers to create stub implementations of the exception,
regardless of platform.
Again, to be sure of interoperability, you need to be experiment a bit. Remember, the calling
language may not have the notion of Exceptions, or at least not be as rigorous as Java in the
rules as to how exceptions must be handled.
1.6.3. What Axis can send via SOAP with restricted Interoperability
Page 17
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
it as an endpoint for SOAP calls or as a parameter in other calls. Instead you must use some
other reference mechanism, such as storing them in a HashMap with numeric or string keys
that can be passed over the wire.
Page 18
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
map into Java in particular ways. Axis gives you the ability to write custom
serializers/deserializers, and some tools to help make your life easier when you do so.
TBD - this section will be expanded in a future version! For now look at the
DataSer/DataDeser classes (in samples/encoding). Also look at the BeanSerializer,
BeanDeserializer, ArraySerializer, ArrayDeserializer and other classes in the
org.apache.axis.encoding.ser package.
Page 19
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.7.2. WSDL2Java: Building stubs, skeletons, and data types from WSDL
Page 20
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
This will generate only those bindings necessary for the client. Axis follows the JAX-RPC
specification when generating Java client bindings from WSDL. For this discussion, assume
we executed the following:
% cd samples/addr
% java org.apache.axis.wsdl.WSDL2Java AddressBook.wsdl
The generated files will reside in the directory "AddressFetcher2". They are put here because
that is the target namespace from the WSDL and namespaces map to Java packages.
Namespaces will be discussed in detail later.
WSDL clause Java class(es) generated
For each entry in the type section A java class
There is an Ant Task to integrate this action with an Ant based build process.
1.7.2.2. Types
The Java class generated from a WSDL type will be named from the WSDL type. This class
will typically, though not always, be a bean. For example, given the WSDL (the WSDL used
throughout the WSDL2Java discussion is from the Address Book sample):
<xsd:complexType name="phone">
<xsd:all>
<xsd:element name="areaCode" type="xsd:int"/>
<xsd:element name="exchange" type="xsd:string"/>
<xsd:element name="number" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
WSDL2Java will generate:
public class Phone implements java.io.Serializable {
public Phone() {...}
public int getAreaCode() {...}
public void setAreaCode(int areaCode) {...}
public java.lang.String getExchange() {...}
public void setExchange(java.lang.String exchange) {...}
public java.lang.String getNumber() {...}
public void setNumber(java.lang.String number) {...}
Page 21
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.7.2.4. Holders
This type may be used as an inout or out parameter. Java does not have the concept of
inout/out parameters. In order to achieve this behavior, JAX-RPC specifies the use of holder
classes. A holder class is simply a class that contains an instance of its type. For example, the
holder for the Phone class would be:
package samples.addr.holders;
public final class PhoneHolder implements javax.xml.rpc.holders.Holder {
public samples.addr.Phone value;
public PhoneHolder() {
}
public PhoneHolder(samples.addr.Phone value) {
this.value = value;
}
Page 22
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
}
A holder class is only generated for a type if that type is used as an inout or out parameter.
Note that the holder class has the suffix "Holder" appended to the class name, and it is
generated in a sub-package with the "holders".
The holder classes for the primitive types can be found in javax.xml.rpc.holders.
1.7.2.5. PortTypes
The Service Definition Interface (SDI) is the interface that's derived from a WSDL's
portType. This is the interface you use to access the operations on the service. For example,
given the WSDL:
<message name="empty">
<message name="AddEntryRequest">
<part name="name" type="xsd:string"/>
<part name="address" type="typens:address"/>
</message>
<portType name="AddressBook">
<operation name="addEntry">
<input message="tns:AddEntryRequest"/>
<output message="tns:empty"/>
</operation>
</portType>
WSDL2Java will generate:
public interface AddressBook extends java.rmi.Remote {
public void addEntry(String name, Address address) throws
java.rmi.RemoteException;
}
A note about the name of the SDI. The name of the SDI is typically the name of the
portType. However, to construct the SDI, WSDL2Java needs information from both the
portType and the binding. (This is unfortunate and is a topic of discussion for WSDL version
2.)
JAX-RPC says (section 4.3.3): "The name of the Java interface is mapped from the name
attribute of the wsdl:portType element. ... If the mapping to a service definition interface uses
elements of the wsdl:binding ..., then the name of the service definition interface is mapped
from the name of the wsdl:binding element."
Note the name of the spec. It contains the string "RPC". So this spec, and WSDL2Java,
assumes that the interface generated from the portType is an RPC interface. If information
from the binding tells us otherwise (in other words, we use elements of the wsdl:binding),
then the name of the interface is derived instead from the binding.
Why? We could have one portType - pt - and two bindings - bRPC and bDoc. Since
document/literal changes what the interface looks like, we cannot use a single interface for
Page 23
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
both of these bindings, so we end up with two interfaces - one named pt and another named
bDoc - and two stubs - bRPCStub (which implements pt) and bDocStub (which implements
bDoc).
Ugly, isn't it? But you can see why it's necessary. Since document/literal changes what the
interface looks like, and we could have more than one binding referring to a single portType,
we have to create more than one interface, and each interface must have a unique name.
1.7.2.6. Bindings
A Stub class implements the SDI. Its name is the binding name with the suffix "Stub". It
contains the code which turns the method invocations into SOAP calls using the Axis Service
and Call objects. It stands in as a proxy (another term for the same idea) for the remote
service, letting you call it exactly as if it were a local object. In other words, you don't need
to deal with the endpoint URL, namespace, or parameter arrays which are involved in
dynamic invocation via the Service and Call objects. The stub hides all that work for you.
Given the following WSDL snippet:
<binding name="AddressBookSOAPBinding" type="tns:AddressBook">
...
</binding>
WSDL2Java will generate:
public class AddressBookSOAPBindingStub extends org.apache.axis.client.Stub
implements AddressBook {
public AddressBookSOAPBindingStub() throws org.apache.axis.AxisFault {...}
public AddressBookSOAPBindingStub(URL endpointURL,
javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {...}
public AddressBookSOAPBindingStub(javax.xml.rpc.Service service)
throws org.apache.axis.AxisFault {...}
public void addEntry(String name, Address address)
throws RemoteException {...}
}
1.7.2.7. Services
Normally, a client program would not instantiate a stub directly. It would instead instantiate a
service locator and call a get method which returns a stub. This locator is derived from the
service clause in the WSDL. WSDL2Java generates two objects from a service clause. For
example, given the WSDL:
<service name="AddressBookService">
<port name="AddressBook" binding="tns:AddressBookSOAPBinding">
<soap:address location="http://localhost:8080/axis/services/AddressBook"/>
Page 24
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
</port>
</service>
WSDL2Java will generate the service interface:
public interface AddressBookService extends javax.xml.rpc.Service {
public String getAddressBookAddress();
public AddressBook getAddressBook() throws javax.xml.rpc.ServiceException;
public AddressBook getAddressBook(URL portAddress)
throws javax.xml.rpc.ServiceException;
}
WSDL2Java will also generate the locator which implements this interface:
public class AddressBookServiceLocator extends org.apache.axis.client.Service
implements AddressBookService {
...
}
The service interface defines a get method for each port listed in the service element of the
WSDL. The locator is the implementation of this service interface. It implements these get
methods. It serves as a locator for obtaining Stub instances. The Service class will by default
make a Stub which points to the endpoint URL described in the WSDL file, but you may also
specify a different URL when you ask for the PortType.
A typical usage of the stub classes would be as follows:
public class Tester {
public static void main(String [] args) throws Exception {
// Make a service
AddressBookService service = new AddressBookServiceLocator();
// Now use the service to get a stub which implements the SDI.
AddressBook port = service.getAddressBook();
// Make the actual call
Address address = new Address(...);
port.addEntry("Russell Butek", address);
}
}
Page 25
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
If you don't specify the "--skeletonDeploy true" option, a skeleton will not be generated.
Instead, the generated deploy.wsdd will indicate that the implementation class is deployed
directly. In such cases, the deploy.wsdd contains extra meta data describing the operations
and parameters of the implementation class. Here is how you run WSDL2Java to deploy
directly to the implementation:
% java org.apache.axis.wsdl.WSDL2Java --server-side AddressBook.wsdl
And here are the server side files that are generated:
WSDL clause Java class(es) generated
For each binding An implementation template class
For all services One deploy.wsdd file with operation meta data
1.7.2.9. Bindings
Page 26
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.7.2.12. Services
The tool also builds you a "deploy.wsdd" and an "undeploy.wsdd" for each service for use
with the AdminClient. These files may be used to deploy the service once you've filled in the
methods of the Implementation class, compiled the code, and made the classes available to
your Axis engine.
Page 27
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
widgets (samples/userguide/example6/WidgetPrice.java):
package samples.userguide.example6;
/**
* Interface describing a web service to set and get Widget prices.
**/
public interface WidgetPrice {
public void setWidgetPrice(String widgetName, String price);
public String getWidgetPrice(String widgetName);
}
Note: If you compile your class with debug information, Java2WSDL will use the debug
information to obtain the method parameter names.
Page 28
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
Use the generated WSDL file to build the appropriate client/server bindings for the web
service (see WSDL2Java):
% java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s -S true
-Nurn:Example6 samples.userguide.example6 wp.wsdl
This will generate the following files:
• WidgetPriceSoapBindingImpl.java : Java file containing the default server
implementation of the WidgetPrice web service.
You will need to modify the *SoapBindingImpl file to add your implementation (see
samples/userguide/example6/WidgetPriceSoapBindingImpl.java).
• WidgetPrice.java: New interface file that contains the appropriate
java.rmi.Remote usages.
• WidgetPriceService.java: Java file containing the client side service interface.
• WidgetPriceServiceLocator.java: Java file containing the client side service
implementation class.
• WidgetPriceSoapBindingSkeleton.java: Server side skeleton.
• WidgetPriceSoapBindingStub.java: Client side stub.
• deploy.wsdd: Deployment descriptor
• undeploy.wsdd: Undeployment descriptor
• (data types): Java files will be produced for all of the other types and holders necessary
for the web service. There are no additional files for the WidgetPrice web service.
Now you have all of the necessary files to build your client/server side code and deploy the
web service!
Page 29
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
Page 30
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
• javax.xml.rpc.holders.IntHolder
• javax.xml.rpc.holders.IntegerWrapperHolder
• javax.xml.rpc.holders.LongHolder
• javax.xml.rpc.holders.LongWrapperHolder
• javax.xml.rpc.holders.ObjectHolder
• javax.xml.rpc.holders.QNameHolder
• javax.xml.rpc.holders.ShortHolder
• javax.xml.rpc.holders.ShortWrapperHolder
• javax.xml.rpc.holders.StringHolder
• javax.xml.rpc.namespace.QName
• javax.xml.rpc.server.ServiceLifecycle
• javax.xml.rpc.soap.SOAPFault
• javax.xml.rpc.soap.SOAPHeaderFault
• javax.xml.transform.Source
• Axis interfaces. These have less guarantees of stability:
• org.apache.axis.AxisFault
• org.apache.axis.Handler
• org.apache.axis.DefaultEngineConfigurationFactory
• org.apache.axis.EngineConfiguration
• org.apache.axis.EngineConfigurationFactory
• org.apache.axis.Message
• org.apache.axis.MessageContext
• org.apache.axis.SOAPPart
• org.apache.axis.client.Call
• org.apache.axis.client.Service
• org.apache.axis.client.ServiceFactory
• org.apache.axis.client.Stub
• org.apache.axis.client.Transport
• org.apache.axis.description.TypeDesc
• org.apache.axis.description.AttributeDesc
• org.apache.aixs.description.ElementDesc
• org.apache.axis.encoding.DeserializationContext
• org.apache.axis.encoding.Deserializer
• org.apache.axis.encoding.DeserializerFactory
• org.apache.axis.encoding.DeserializerTarget
• org.apache.axis.encoding.FieldTarget
• org.apache.axis.encoding.MethodTarget
• org.apache.axis.encoding.SerializationContext
• org.apache.axis.encoding.Serializer
• org.apache.axis.encoding.SerializerFactory
Page 31
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
• org.apache.axis.encoding.SimpleType
• org.apache.axis.encoding.Target
• org.apache.axis.encoding.TypeMapping
• org.apache.axis.encoding.TypeMappingRegistry
• org.apache.axis.encoding.ser.BaseDeserializerFactory
• org.apache.axis.encoding.ser.BaseSerializerFactory
• org.apache.axis.encoding.ser.BeanPropertyTarget
• org.apache.axis.encoding.ser.SimpleSerializer
• org.apache.axis.encoding.ser.SimpleDeserializer
• org.apache.axis.session.Session
• org.apache.axis.transport.http.SimpleAxisServer
• org.apache.axis.transport.jms.SimpleJMSListener
• org.apache.axis.utils.BeanProperty
• org.apache.axis.wsdl.WSDL2Java
• org.apache.axis.wsdl.Java2WSDL
Page 32
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.9.2.1. org.apache.axis.MessageContext
The answer to most "where do I find..." questions for an Axis web service is "in the
MessageContext." Essentially everything Axis knows about a given request/response can be
retrieved via the MessageContext. Here Axis stores:
• A reference to the AxisEngine
• The request and response messages (org.apache.axis.Message objects available
via getter and setter methods)
• Information about statefulness and service scope (whether the service is maintaining
session information, etc.)
• The current status of processing (whether or not the "pivot" has been passed, which
determines whether the request or response is the current message)
• Authentication information (username and password, which can be provided by a servlet
container or other means)
• Properties galore. Almost anything you would want to know about the message can be
retrieved via MessageContext.getProperty(). You only need to know the name
of the property. This can be tricky, but it is usually a constant, like those defined in
org.apache.axis.transport.http.HTTPConstants. So, for example, to
retrieve the ServletContext for the Axis Servlet, you would want:
((HttpServlet)msgC.getProperty(HTTPConstants.MC_HTTP_SERVLET)).getServl
From within your service, the current MessageContext object is always available via the
static method MessageContext.getCurrentContext(). This allows you to do any
needed customization of the request and response methods, even from within an RPC service
that has no explicit reference to the MessageContext.
1.9.2.2. org.apache.axis.Message
An org.apache.axis.Message object is Axis's representation of a SOAP message.
The request and response messages can be retrieved from the MessageContext as described
above. A Message has:
• MIME headers (if the message itself has MIME information)
• Attachments (if the message itself has attachments)
• A SOAPPart (and a convenience method for quick retrieval of the SOAPPart's
SOAPEnvelope). The SOAPPart gives you access to the SOAP "guts" of the message
(everything inside the <soap:Envelope> tags)
Page 33
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
1.9.2.3. org.apache.axis.SOAPEnvelope
As you can see, starting with the MessageContext lets you work your way down through the
API, discovering all the information available to you about a single request/response
exchange. A MessageContext has two Messages, which each have a SOAPPart that contains
a SOAPEnvelope. The SOAPEnvelope, in turn, holds a full representation of the SOAP
Envelope that is sent over the wire. From here you can get and set the contents of the SOAP
Header and the SOAP Body. See the Javadocs for a full list of the properties available.
To use the program, you should select a local port which tcpmon will monitor for incoming
connections, a target host where it will forward such connections, and the port number on the
target machine which should be "tunneled" to. Then click "add". You should then notice
another tab appearing in the window for your new tunneled connection. Looking at that
panel, you'll see something like this:
Now each time a SOAP connection is made to the local port, you will see the request appear
in the "Request" panel, and the response from the server in the "Response" panel. Tcpmon
keeps a log of all request/response pairs, and allows you to view any particular pair by
selecting an entry in the top panel. You may also remove selected entries, or all of them, or
choose to save to a file for later viewing.
The "resend" button will resend the request you are currently viewing, and record a new
response. This is particularly handy in that you can edit the XML in the request window
before resending - so you can use this as a great tool for testing the effects of different XML
on SOAP servers. Note that you may need to change the content-length HTTP header value
before resending an edited request.
Page 34
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.
WebServices - Axis
In this utility, a handler has been written and added to the global handler chain. As SOAP
requests and responses are received, the SOAP message information is forwarded to a SOAP
monitor service where it can be displayed using a web browser interface.
The SOAP message information is accessed with a web browser by going to
http://localhost:<port>/axis/SOAPMonitor (where <port> is the port number where the
application server is running).
The SOAP message information is displayed through a web browser by using an applet that
opens a socket connection to the SOAP monitor service. This applet requires a Java plug-in
1.3 or higher to be installed in your browser. If you do not have a correct plug-in, the browser
should prompt you to install one.
The port used by the SOAP monitor service to comminicate with applets is configurable. Edit
the web.xml file for the Axis web application to change the port to be used.
Note: The SOAP Monitor is NOT enabled by default for security reasons. To enable it, read
Enabling the SOAP Monitor in the Installation instructions.
1.12. Glossary
Handler
A reusable class which is responsible for processing a MessageContext in some
custom way. The Axis engine invokes a series of Handlers whenever a request
comes in from a client or a transport listener.
SOAP
The Simple Object Access Protocol (yes, despite the fact that it sometimes
doesn't seem so simple, and doesn't have anything to do with objects... :)). You
can read the SOAP 1.1 specification at http://www.w3.org/TR/soap. The W3C is
currently in the midst of work on SOAP 1.2, under the auspices of the XML
Protocol Group.
Provider
A provider is the "back-end" Handler which is responsible for actually performing
the "meat" of the desired SOAP operation. Typically this means calling a method
on some back-end service object. The two commonly used providers are
RPCProvider and MsgProvider, both in the org.apache.axis.providers.java
package.
Page 35
Copyright © 2000-2005 The Apache Software Foundation All rights reserved.