Anda di halaman 1dari 14

Introduction to Apache Axis Web Services

March 29th, 2010 Vinay Leave a comment Go to comments

In our first post Introduction to webservices , we had covered basic of web services and its
architecture . In this post , we will installation of axis engine and implementation of web services

Installation of AXIS Engine

Apache Axis is an Open Source SOAP server and client. SOAP is a mechanism for inter-
application communication between systems written in arbitrary languages, across the Internet.
SOAP usually exchanges messages over HTTP: the client POSTs a SOAP request, and receives
either an HTTP success code and a SOAP response or an HTTP error code.

SOAP messages are XML messages. These messages exchange structured information between
SOAP systems. Messages consist of one or more SOAP elements inside an envelope, Headers
and the SOAP Body. SOAP has two syntaxes for describing the data in these elements, Section
5, which is a clear descendant of the XML RPC system, and XML Schema, which is the better
system. Axis handles the magic of converting Java objects to SOAP data when it sends it over
the wire or receives results. SOAP Faults are sent by the server when something goes wrong;
Axis converts these to Java exceptions.

Axis is compiled in the JAR file axis.jar; it implements the JAX-RPC API declared in the JAR
files jaxrpc.jar and saaj.jar. It needs various helper libraries, for logging, WSDL processing and
introspection. All these files can be packaged into a web application, axis.war that can be
dropped into a servlet container. Axis ships with some sample SOAP services. You can add your
own by adding new compiled classes to the Axis webapp and registering them.

Before doing all this you have to first install Axis server in your web application server.

AXIS Installation

First step in installation of axis SOAP engine on web application server is find the directory into
which web applications (“webapps”) are to be placed. Into this directory copy the “/axis”
directory from the xml-axis distribution. We are using Tomcat as web application server, so put
this /axis directory in webapp folder of application server.

Axis needs to be able to find an XML parser. The recommended one is Xcers jars from
http://xml.apache.org/dist/xerces-j/ although you can also add parser of your choice, which is
based on JAXP 1.1 XML specifications. These jar files need to be add in parser’s libraries to
axis/WEB-INF/lib.

Deploy service on Axis

To deploy a new service on soap engine, two steps need to be followed:


1. Get the classes and libraries of your new service into the Axis WAR directory tree.
2. Tell the Axis Engine about the new file.

For first step i.e. to add your code to the server:

In the WEB-INF directory, look for (or create) a “classes” directory (i.e. axis/WEB-INF/classes).
In this directory, copy the compiled Java classes you wish to install, being careful to preserve the
directory structure of the Java packages.

If your classes’ services are already packaged into JAR files, feel free to drop them into the
WEB-INF/lib directory instead. Also add any third party libraries you depend on into the same
directory. After addition of library and class files you must have to restart webapp. This can be
done by restarting the web application server.

For second step i.e. to tell the server or Axis Engine for the wed service you must have to
declare the service and service files in Web Service Deployment Descriptor (WSDD) file which
is an XML file located in WEB-INF directory of the axis server. By default Axis saves it state
into the global configuration file axis/WEB-INF/server-config.wsdd.

JAR files required and Class Path Set up for Axis:

To run web service applications few jar files are required and java must be able to find out these
jars: axis.jar, commons-discovery.jar, commons-logging.jar, jaxrpc.jar, saaj.jar, log4j-1.2.8.jar
and the XML parser jar file or files (e.g., xerces.jar). These jar files must be put within the lib
directory if the axis. As these jar files must be detected by java, so AXISCLASSPATH
environment must be setup as:

set AXIS_HOME=c:\axis

set AXIS_LIB=%AXIS_HOME%\lib

set AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar;

%AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;

%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

Advanced Installation: adding Axis to your own Webapp

If you are experienced in web application development, and especially if you wish to add web
services to an existing or complex webapp, you can take an alternate approach to running Axis.
Instead of adding your classes to the Axis webapp, you can add Axis to your application.

1. The core concepts are


2. Add axis.jar, wsdl.jar, saaj.jar, jaxrpc.jar and the other dependent libraries to your WAR
file.
3. Copy all the Axis Servlet declarations and mappings from axis/WEB-INF/web.xml and
add them to your own web.xml
4. Build and deploy your webapp.
5. Run the Axis AdminClient against your own webapp, instead of Axis, by changing the
URL you invoke it with.

5 Introduction to SOAP and WSDL

SOAP (Simple Object Access Protocol) is an XML-based communication protocol and encoding
format for inter-application communication. It provides a way to communicate between
applications running on different operating systems, with different technologies and
programming languages. Key features of SOAP are platform independent, Language
Independent, based on xml and can get around firewalls. So, it is a lightweight and a loosely
coupled protocol for exchange of information in a decentralized and a distributed environment.

Finally, SOAP establishes a set of rules that enable clients and servers to do remote procedure
invocation using SOAP as a communications framework. SOAP — at base a message-oriented
protocol — can, with these conventions, work well as an RPC-type protocol. Object serialization
is the mechanism that gives SOAP-RPC its punch.

Message Format

SOAP does all this in the context of a standardized message format. The primary part of this
message has a MIME type of “text/xml” and contains the SOAP envelope. This envelope is an
XML document. The envelope contains a header (optional) and a body (mandatory). The body
part of the envelope is always intended for the final recipient of the message, while the header
entries may target the nodes that perform intermediate processing. Attachments, binary or
otherwise, may be appended to the body.

The SOAP 1.1 spec provides the following sample envelope:

<SOAP-ENV: Envelope
  xmlns:
    SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:
    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Header>
        <t:Transaction xmlns:t="some-URI"
                SOAP-ENV:mustUnderstand="1"> 5
        </t:Transaction>
      </SOAP-ENV:Header>
      <SOAP-ENV:Body>
        <m:GetLastTradePrice xmlns:m="some-URI">
                <symbol>DEF</Symbol>
        </m: GetLastTradePrice>
      </SOAP-ENV:Body>
</SOAP-Envelope>
In this example, a GetLastTradePrice request is being sent to a stock-quote service somewhere
on the Web. The request takes a string parameter, a ticker symbol, and returns a float in the
SOAP response.

The SOAP envelope is the top element of the XML document that represents the SOAP message.
XML namespaces are used to disambiguate SOAP identifiers from application specific
identifiers. XML namespaces are used heavily in SOAP to qualify or scope elements in the
message to a specific domain. To understand SOAP namespaces, it helps to be familiar with the
namespace spec for XML. If you’re not, simply think of namespaces as neighborhood identifiers
that help uniquely identify SOAP elements by associating them with specific locations, real or
imagined.

Namespaces
The first namespace in the example references the SOAP schema, which defines the elements
and attributes in the SOAP message. The second namespace refers to SOAP encodings. Since no
additional per-element encoding is specified, this encoding applies to the whole document.

Header
The first element identified in this sample SOAP envelope header is a transaction element,
accompanied by a namespace attribute and by the mustUnderstand attribute with a value of 1.
Since mustUnderstand is set to 1, the server accepting this message must perform intermediate
processing on this transaction node. You can interpret this to mean that the server and client have
previously agreed upon the semantics that govern the processing of this header element, so that
the server knows exactly what to do with the contents of the element, in this case 5.

If the server receiving this message doesn’t understand the semantics of the transaction header, it
is required to reject the request completely and throw a fault. A fault element is a special part of
the SOAP body and a well-defined mechanism to ship error information back to the client.

Intermediate processing nodes like this are an example of SOAP’s extensibility. Clients include
such nodes in a SOAP message to indicate that special processing needs to take place before the
contents of the message body can be processed. Ensuring backward compatibility with existing
servers not capable of providing such processing is simply a matter of setting the
mustUnderstand attribute to 0, which makes the action optional.

In addition to defining transaction nodes like the one described above, a SOAP message may
optionally contain header entries specifying nodes that perform authorization processing,
encryption, persistence of state, business logic processing and so on. Headers help make SOAP a
modular, extensible packaging model. Just keep in mind that header processing is entirely
independent of the SOAP message body.

Body
The SOAP body in the example contains an XML payload, which we can surmise, without really
seeing it spelled out for us, does RPC. SOAP is not only a modular packaging model, it’s also a
fairly cryptic packaging model.
Lets take a look at a very simple SOAP message.

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<helloWorld/>
</Body>
</Envelope>

Note the use of the xmlsoap namespace.  This identifies the Envelope as a SOAP Envelope.  The
Envelope has one Body.  The body has one element.

The above, while simple, has a bug in it.  The hello world element is in the default namespace,
which in this case is the SOAP Envelope.  Let’s make the simplest fix possible to correct this:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<helloWorld xmlns="http://www.soapware.org/"/>
</Body>
</Envelope>

Namespaces merely allow one to specify which helloWorld procedure is desired.  For
background on why this is important, see, What Object does SOAP Access?

The following is just a style issue – it does not change the meaning of the message, but most
SOAP messages you see chose not to make the envelope the default namespace but rather prefer
to explicitly qualify it.  The resulting message looks like this:

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<m:helloWorld xmlns:m="http://www.soapware.org/"/>
</SOAP:Body>
</SOAP:Envelope>

Now let’s change the name of the procedure, and add an argument.

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<m:getStateName xmlns:m="http://www.soapware.org/">
<statenum>41</statenum>
</m:getStateName>
</SOAP:Body>
</SOAP:Envelope>

Suppose we wanted to support an option to indicate a preference for a state abbreviation instead. 
Servers that don’t implement this but follow the rule that “The server must ignore all elements
that it doesn’t understand.” will continue to accept this message.

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<m:getStateName xmlns:m="http://www.soapware.org/">
<statenum>41</statenum>
<format>abbreviation</format>
</m:getStateName>
</SOAP:Body>
</SOAP:Envelope>

What we have actually done to this point is actually send an XML document.  Since our intent is
to encode a remote procedure call it may be helpful to clue the recipient in on this fact up front.

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"
SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP:Body>
<m:getStateName xmlns:m="http://www.soapware.org/">
<statenum>41</statenum>
</m:getStateName>
</SOAP:Body>
</SOAP:Envelope>

Now lets declare the statenum as a 32 bit integer:

<SOAP:Envelope xmlns:SOAP=http://schemas.xmlsoap.org/soap/envelope/
SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP:Body>
<m:getStateName xmlns:m="http://www.soapware.org/">
<statenum xsi:type="xsd:int">41</statenum>
</m:getStateName>
</SOAP:Body>
</SOAP:Envelope>

In many cases, such an addition is not necessary or appropriate.  Perhaps the data type could be
predetermined and captured in a document such as a WSDL.  Alternatively, the data type could
be dynamically determined by the recipient.  But for the cases where adding the data type is
appropriate, the above demonstrates how it is done.

WSDL (Web Services Description Language)

The Web Services Description Language (WSDL) is an XML language for describing the
syntax of Web Service interfaces and their locations. The WSDL specification calls it “an XML
format for describing network services as a set of endpoints operating on messages containing
either document-oriented or procedure-oriented information.” Within that context, the diagram
below illustrates the elements that are present in a WSDL document, and shows how they are
related.

WSDL Layout
The WSDL standard is being worked out by the W3C (World Wide Web Consortium). That
body further defines the standard as “an XML format for describing network services as a set of
endpoints operating on messages containing either document-oriented or procedure-oriented
information. The operations and messages are described abstractly, and then bound to a concrete
network protocol and message format to define an endpoint. Related concrete endpoints are
combined into abstract endpoints (services). WSDL is extensible to allow description of
endpoints and their messages regardless of what message formats or network protocols are used
to communicate.”

The following diagram illustrates how a Web service is registered, found and called in a scenario
based on Java technology. In this diagram, the Web service is registered in a UDDI repository
using the Java API for XML Registries (JAXR), where a business partner or other system can
find the service. The registry information from UDDI is used to locate a WSDL document that
details the call semantics for the Web service. With the WSDL document in hand, the Java
programmer can then feed it to a tool that can generate a Java object proxy to the Web service, or
simply use it as a reference document along with a lower-level SOAP API.

WSDL Working

A WSDL document has a definitions element that contains the types, message, portType,
binding, and service elements as described below:

Definition

Defines one or more services. A definition element supports the following attributes:

 name is optional.
 targetNamespace is the logical namespace for information about this service. WSDL
documents can import other WSDL documents, and setting targetNamespace to a
unique value ensures that the namespaces do not clash.
 xmlns is the default namespace of the WSDL document, and it is set to
http://schemas.xmlsoap.org/wsdl/. All the WSDL elements, such as <definitions>,
<types> and <message> reside in this namespace.
 xmlns:xsd and xmlns:soap are standard namespace definitions that are used for
specifying SOAP-specific information as well as data types.
 xmlns:tns stands for this namespace.

Types : The types element describes all the data types used between the client and server.
WSDL is not tied exclusively to a specific typing system, but it uses the W3C XML Schema
specification as its default choice. If the service uses only XML Schema built-in simple types,
such as strings and integers, the types element is not required.

Standard mappings from WSDL to Java

xsd:base64Binary byte[]
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
xsd:QName javax.xml.namespace.QName
xsd:short short
xsd:string java.lang.String

Message

The message element describes a one-way message, whether it is a single message request or a
single message response. It defines the name of the message and contains zero or more message
part elements, which can refer to message parameters or message return values.

PortType

The portType element combines multiple message elements to form a complete one-way or
round-trip operation. For example, a portType can combine one request and one response
message into a single request/response operation, most commonly used in SOAP services. Note
that a portType can (and frequently does) define multiple operations.

Binding
The binding element describes the concrete specifics of how the service will be implemented on
the wire. WSDL includes built-in extensions for defining SOAP services, and SOAP-specific
information therefore goes here.

Service

The service element defines the address for invoking the specified service. Most commonly, this
includes a URL for invoking the SOAP service.

Documentation

The documentation element is used to provide human-readable documentation and can be


included inside any other WSDL element.

Import

The import element is used to import other WSDL documents or XML Schemas. This enables
more modular WSDL documents. For example, two WSDL documents can import the same
basic elements and yet include their own service elements to make the same service available at
two physical addresses. Note, however, that not all WSDL tools support the import functionality
as of yet.

Basic WSDL Example: HelloService.wsdl


The service provides a single publicly available function, called sayHello. The function expects a
single string parameter, and returns a single string greeting. For example, if you pass the
parameter world, the service returns the greeting, “Hello, world!”

               <?xml version="1.0" encoding="UTF-8"?>


<definitions
   targetNamespace="http://www.myService.com/wsdl/HelloService.wsdl"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns="http://www.ecerami.com/wsdl/HelloService.wsdl"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
   <message>
      <part/>
   </message>
   <message>
      <part/>
   </message>
 
   <portType>
      <operation>
         <input message="tns:SayHelloRequest"/>
         <output message="tns:SayHelloResponse"/>
      </operation>
   </portType>
  
   <binding>
      <soap:binding style="rpc"
         transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation>
         <soap:operation soapAction="sayHello"/>
         <input>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:helloservice"
               use="encoded"/>
         </input>
         <output>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:helloservice"
               use="encoded"/>
         </output>
      </operation>
   </binding>
 
   <service>
      <documentation>WSDL File for HelloService</documentation>
      <port binding="tns:Hello_Binding">
         <soap:address            
location="http://localhost:8080/soap/servlet/rpcrouter"/>
      </port>
   </service>
</definitions>

Now lets discuss elements of HelloWorld.wsdl

definitions

The definitions element specifies that this document is the HelloService. It also specifies
numerous namespaces that will be used throughout the remainder of the document:

<definitions
  targetNamespace="http://www.myService.com/wsdl/HelloService.wsdl"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns="http://www.ecerami.com/wsdl/HelloService.wsdl"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">

The use of namespaces is important for differentiating elements, and it enables the document to
reference multiple external specifications, including the WSDL specification, the SOAP
specification, and the XML Schema specification.

The definitions element also specifies a targetNamespace attribute. The targetNamespace is a


convention of XML Schema that enables the WSDL document to refer to itself. In Example 6-1,
we specified a targetNamespace of http://www.ecerami.com/wsdl/HelloService.wsdl. Note,
however, that the namespace specification does not require that the document actually exist at
this location; the important point is that you specify a value that is unique, different from all
other namespaces that are defined.

Finally, the definitions element specifies a default namespace:


xmlns=http://schemas.xmlsoap.org/wsdl/. All elements without a namespace prefix, such as
message or portType, are therefore assumed to be part of the default WSDL namespace.

message

Two message elements are defined. The first represents a request message, SayHelloRequest, and
the second represents a response message, SayHelloResponse:

<message>
   <part/>
</message>
<message>
   <part/>
</message>

Each of these messages contains a single part element. For the request, the part specifies the
function parameters; in this case, we specify a single firstName parameter. For the response, the
part specifies the function return values; in this case, we specify a single greeting return value.

The part element’s type attribute specifies an XML Schema data type. The value of the type
attribute must be specified as an XML Schema QName–this means that the value of the attribute
must be namespace-qualified. For example, the firstName type attribute is set to xsd:string; the
xsd prefix references the namespace for XML Schema, defined earlier within the definitions
element.

If the function expects multiple arguments or returns multiple values, you can specify multiple
part elements.

portType

The portType element defines a single operation, called sayHello. The operation itself consists of
a single input message (SayHelloRequest) and a single output message (SayHelloResponse):

<portType>
   <operation>
      <input message="tns:SayHelloRequest"/>
      <output message="tns:SayHelloResponse"/>
   </operation>
</portType>

Much like the type attribute defined earlier, the message attribute must be specified as an XML
Schema QName. This means that the value of the attribute must be namespace-qualified. For
example, the input element specifies a message attribute of tns:SayHelloRequest; the tns prefix
references the targetNamespace defined earlier within the definitions element.
WSDL supports four basic patterns of operation:

One-way

The service receives a message. The operation therefore has a single input element.

Request-response

The service receives a message and sends a response. The operation therefore has one input
element, followed by one output element (illustrated previously in Example). To encapsulate
errors, an optional fault element can also be specified.

Solicit-response

The service sends a message and receives a response. The operation therefore has one output
element, followed by one input element. To encapsulate errors, an optional fault element can also
be specified.

Notification

The service sends a message. The operation therefore has a single output element.

These patterns of operation are also shown below

Operation patterns supported by WSDL

binding

The binding element provides specific details on how a portType operation will actually be
transmitted over the wire. Bindings can be made available via multiple transports, including
HTTP GET, HTTP POST, or SOAP. In fact, you can specify multiple bindings for a single
portType.

The binding element itself specifies name and type attributes:

<binding>

The type attribute references the portType defined earlier in the document. In our case, the
binding element therefore references tns:Hello_PortType, defined earlier in the document. The
binding element is therefore saying, “I will provide specific details on how the sayHello
operation will be transported over the Internet.”

SOAP binding
WSDL 1.1 includes built-in extensions for SOAP 1.1. This enables you to specify SOAP-specific
details, including SOAP headers, SOAP encoding styles, and the SOAPAction HTTP header.
The SOAP extension elements include:

soap:binding

This element indicates that the binding will be made available via SOAP. The style attribute
indicates the overall style of the SOAP message format. A style value of rpc specifies an RPC
format. This means that the body of the SOAP request will include a wrapper XML element
indicating the function name. Function parameters are then embedded inside the wrapper
element. Likewise, the body of the SOAP response will include a wrapper XML element that
mirrors the function request. Return values are then embedded inside the response wrapper
element.

A style value of document specifies an XML document call format. This means that the request
and response messages will consist simply of XML documents. The document style is flatter
than the rpc style and does not require the use of wrapper elements. (See the upcoming note for
additional details.)

The transport attribute indicates the transport of the SOAP messages. The value
http://schemas.xmlsoap.org/soap/http indicates the SOAP HTTP transport, whereas
http://schemas.xmlsoap.org/soap/smtp indicates the SOAP SMTP transport.

soap:operation

This element indicates the binding of a specific operation to a specific SOAP implementation.
The soapAction attribute specifies that the SOAPAction HTTP header be used for identifying the
service. (See Chapter 3 for details on the SOAPAction header.)

soap:body

This element enables you to specify the details of the input and output messages. In the case of
HelloWorld, the body element specifies the SOAP encoding style and the namespace URN
associated with the specified service.

service

The service element specifies the location of the service. Because this is a SOAP service, we use
the soap:address element, and specify the local host address for the Apache SOAP rpcrouter
servlet: http://localhost:8080/soap/servlet/rpcrouter.

7 Creating new Web Services Project

To write and deploy the web services you just have to follow a few simple steps:
1. Define web services Interface: This is done with WSDL as per WSDL specs discussed
above.
2. Then with the use of WSDL2JAVA tool generate java code. This will generate service
interface, its implementation class, service locator class and service stub class.
3. Define Deployment parameters of the service in WSDD (Web Services Deployment
Descriptor) file
4. Compile and generate the war file and deploy the service in axis server as mentioned
above.
5. Now to use this web service, write a client that uses generated stubs to access the web
service.

All we need to do in the code is to get access to the service via the ServiceLocator, and then call
methods on the remote handle that we have to the service. As shown below

package webservice
public class SomeServiceTester{
  public static void main(String [] args) throws Exception {
    // Make a service
    service.ws.SomeService service =
         new service.ws.SomeServiceLocator();
    // Now use the service to get a stub to the service
    service.ws.Service serv = service.Service();
    // Make the actual call
    System.out.println("Fibonacci(10) = " +
                     serv.someMethod(param1,param2));
    }
}

Anda mungkin juga menyukai