| <?xml version="1.0" encoding="utf-8"?> | |
| <!-- | |
| ~ Licensed to the Apache Software Foundation (ASF) under one | |
| ~ or more contributor license agreements. See the NOTICE file | |
| ~ distributed with this work for additional information | |
| ~ regarding copyright ownership. The ASF licenses this file | |
| ~ to you under the Apache License, Version 2.0 (the | |
| ~ "License"); you may not use this file except in compliance | |
| ~ with the License. You may obtain a copy of the License at | |
| ~ | |
| ~ http://www.apache.org/licenses/LICENSE-2.0 | |
| ~ | |
| ~ Unless required by applicable law or agreed to in writing, | |
| ~ software distributed under the License is distributed on an | |
| ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| ~ KIND, either express or implied. See the License for the | |
| ~ specific language governing permissions and limitations | |
| ~ under the License. | |
| --> | |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
| <html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml"> | |
| <head> | |
| <meta name="generator" content= | |
| "HTML Tidy for Windows (vers 14 June 2007), see www.w3.org" /> | |
| <meta http-equiv="content-type" content= | |
| "application/xhtml+xml; charset=us-ascii" /> | |
| <title>Axis2 Quick Start Guide</title> | |
| </head> | |
| <body xml:lang="en" lang="en"> | |
| <h1>Axis2 Quick Start Guide</h1> | |
| <p>The purpose of this guide is to get you started on creating | |
| services and clients using Axis2 as quickly as possible. We'll take | |
| a simple StockQuote Service and show you some of the different ways | |
| in which you can create and deploy it, as well as take a quick look | |
| at one or two utilities that come with Axis2. We'll then look at | |
| creating clients to access those services.</p> | |
| <h2>Content</h2> | |
| <ul> | |
| <li><a href="#introduction">Introduction</a></li> | |
| <li><a href="#ready">Getting Ready</a></li> | |
| <li><a href="#services">Axis2 services</a></li> | |
| <li><a href="#create">Creating services</a> | |
| <ul> | |
| <li><a href="#deploy">Deploying POJOs</a></li> | |
| <li><a href="#axiom">Building the service using AXIOM</a></li> | |
| <li><a href="#adb">Generating the service using ADB</a></li> | |
| <li><a href="#xmlbeans">Generating the service using | |
| XMLBeans</a></li> | |
| <li><a href="#jibx">Generating the service using JiBX</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="#clients">Generating Clients</a> | |
| <ul> | |
| <li><a href="#clientaxiom">Creating a client using AXIOM</a></li> | |
| <li><a href="#clientadb">Generating a client using ADB</a></li> | |
| <li><a href="#clientxmlbeans">Generating a client using XML | |
| Beans</a></li> | |
| <li><a href="#clientjibx">Generating a client using JiBX</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="#summary">Summary</a></li> | |
| <li><a href="#furtherstudy">For Further Study</a></li> | |
| </ul> | |
| <h3>A Quick Setup Note:</h3> | |
| <p>The code for the document can be found in the extracted <a href= | |
| "../download.cgi">Standard | |
| Binary Distribution</a>, more specifically at Axis2_HOME/samples/ | |
| inside the directories- quickstart, quickstartadb, quickstartaxiom, | |
| quickstartjibx and quickstartxmlbeans. (Consider getting it now as | |
| it will help you to follow along.) It includes Ant buildfiles | |
| (build.xml) that we'll refer to throughout the examples to make | |
| compilation easier.</p> | |
| <a name="introduction" id="introduction"></a> | |
| <h2>Introduction</h2> | |
| <p>Let's start with the service itself. We'll make it simple so you | |
| can see what is going on when we build and deploy the services. A | |
| StockQuoteService example seems to be mandatory in instances like | |
| this one, so let's use the following (see Code Listing 1).</p> | |
| <p><b>Code Listing 1: The StockQuoteService class</b></p> | |
| <pre> | |
| package samples.quickstart.service.pojo; | |
| import java.util.HashMap; | |
| public class StockQuoteService { | |
| private HashMap map = new HashMap(); | |
| public double getPrice(String symbol) { | |
| Double price = (Double) map.get(symbol); | |
| if(price != null){ | |
| return price.doubleValue(); | |
| } | |
| return 42.00; | |
| } | |
| public void update(String symbol, double price) { | |
| map.put(symbol, new Double(price)); | |
| } | |
| } | |
| </pre> | |
| <p>It will be a simple service with two possible calls. One of | |
| which is an in/out message, and the other is an in-only service. | |
| Ultimately, we'll package the service and deploy it in four | |
| different ways.</p> | |
| <p>First, let's look at how this simple Java class corresponds to a | |
| service.</p> | |
| <a name="ready" id="ready"></a> | |
| <h2>Getting Ready</h2> | |
| <p>Before we build anything using Axis2, we have to take care of a | |
| little housekeeping. First off, you'll need to get your environment | |
| ready for working with Axis2. Fortunately, it involves just a few | |
| simple steps:</p> | |
| <ol> | |
| <li>Download and install Java (Minimum version is JDK1.5). Set the | |
| JAVA_HOME environment variable to the pathname of the directory | |
| into which you installed the JDK release.</li> | |
| <li>Download Axis2 and extract it to a target directory.</li> | |
| <li>Copy the axis2.war file to the webapps directory of your | |
| servlet engine.</li> | |
| <li>Set the AXIS2_HOME environment variable to point to the target | |
| directory in step. Note that all of the scripts and build files | |
| Axis2 generates depend on this value, so don't skip this step! | |
| Linux users can alternatively run the setenv.sh file in the | |
| AXIS2_HOME/bin directory to set the AXIS2_HOME environment variable | |
| to the pathname of the extracted directory of Axis2.</li> | |
| </ol> | |
| <p>In most cases, we're also going to need a WSDL file for our | |
| service. Axis2's Java2WSDL can be used to bootstrap a WSDL. To | |
| generate a WSDL file from a Java class, perform the following | |
| steps:</p> | |
| <ol> | |
| <li>Create and compile the Java class. | |
| <pre> | |
| (Windows) | |
| %AXIS2_HOME%\bin\java2wsdl.bat -cp . -cn samples.quickstart.service.pojo.StockQuoteService -of StockQuoteService.wsdl | |
| (Linux) | |
| $AXIS2_HOME/bin/java2wsdl.sh -cp . -cn samples.quickstart.service.pojo.StockQuoteService -of StockQuoteService.wsdl | |
| </pre></li> | |
| <li>Generate the WSDL using the command:</li> | |
| </ol> | |
| <p>Once you've generated the WSDL file, you can make the changes | |
| you need. For example, you might add custom faults or change the | |
| name of the generated elements. For example, this | |
| StockQuoteService.wsdl is in | |
| AXIS2_HOME/samples/quickstartadb/resources/META-INF folder, which | |
| we'll be using throughout the rest of this guide, replaces the | |
| generic parameters created by the generation process.</p> | |
| <a name="services" id="services"></a> | |
| <h2>Axis2 Services</h2> | |
| <p>Before we build anything, it's helpful to understand what the | |
| finished product looks like.</p> | |
| <p>The server side of Axis2 can be deployed on any Servlet engine, | |
| and has the following structure. Shown in Code Listing 2.</p> | |
| <p><b>Code Listing 2: The Directory Structure of axis2.war</b></p> | |
| <pre> | |
| axis2-web | |
| META-INF | |
| WEB-INF | |
| classes | |
| conf | |
| axis2.xml | |
| lib | |
| activation.jar | |
| ... | |
| xmlSchema.jar | |
| modules | |
| modules.list | |
| addressing.mar | |
| ... | |
| soapmonitor.mar | |
| services | |
| services.list | |
| aservice.aar | |
| ... | |
| version.aar | |
| web.xml | |
| </pre> | |
| <p>Starting at the top, axis2-web is a collection of JSPs that make | |
| up the Axis2 administration application, through which you can | |
| perform any action such as adding services and engaging and | |
| dis-engaging modules. The WEB-INF directory contains the actual | |
| java classes and other support files to run any services deployed | |
| to the services directory.</p> | |
| <p>The main file in all this is axis2.xml, which controls how the | |
| application deals with the received messages, determining whether | |
| Axis2 needs to apply any of the modules defined in the modules | |
| directory.</p> | |
| <p>Services can be deployed as *.aar files, as you can see here, | |
| but their contents must be arranged in a specific way. For example, | |
| the structure of this service will be as follows:</p> | |
| <a name="aarstructure" id="aarstructure"></a> | |
| <pre> | |
| - StockQuoteService | |
| - META-INF | |
| - services.xml | |
| - lib | |
| - samples | |
| - quickstart | |
| - service | |
| - pojo | |
| - StockQuoteService.class | |
| </pre> | |
| <p>Here, the name of the service is StockQuoteService, which is | |
| specified in the services.xml file and corresponds to the top-level | |
| folder of this service. Compiled Java classes are placed underneath | |
| this in their proper place based on the package name. The lib | |
| directory holds any service-specific JAR files needed for the | |
| service to run (none in this case) besides those already stored | |
| with the Axis2 WAR file and the servlet container's common JAR | |
| directories. Finally, the META-INF directory contains any | |
| additional information about the service that Axis2 needs to | |
| execute it properly. The services.xml file defines the service | |
| itself and links the Java class to it (See Code Listing 3).</p> | |
| <p><b>Code Listing 3: The Service Definition File</b></p> | |
| <pre> | |
| <service name="StockQuoteService" scope="application"> | |
| <description> | |
| Stock Quote Sample Service | |
| </description> | |
| <messageReceivers> | |
| <messageReceiver | |
| mep="http://www.w3.org/ns/wsdl/in-only" | |
| class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/> | |
| <messageReceiver | |
| mep="http://www.w3.org/ns/wsdl/in-out" | |
| class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> | |
| </messageReceivers> | |
| <parameter name="ServiceClass"> | |
| samples.quickstart.service.pojo.StockQuoteService | |
| </parameter> | |
| </service> | |
| </pre> | |
| <p>Here the service is defined, along with the relevant | |
| messageReceiver types for the different message exchange | |
| patterns.</p> | |
| <p>The META-INF directory is also the location for any custom WSDL | |
| files you intend to include for this application.</p> | |
| <p>You can deploy a service by simply taking this hierarchy of | |
| files and copying it to the webapps/axis2/WEB-INF/services | |
| directory of your servlet engine. (Note the Axis2 WAR file must be | |
| installed first in the servlet engine.) This is known as the | |
| "exploded" format. You can also compress your documents into an | |
| *.aar file, similar to a *.jar file, and place the *.aar file | |
| directly in the servlet engine's webapps/axis2/WEB-INF/services | |
| directory.</p> | |
| <p>Now that you understand what we're trying to accomplish, we're | |
| almost ready to start building.</p> | |
| <p>First, <a href= | |
| "../download.cgi">download</a> | |
| and unzip the appropriate version of Axis2 Standard Binary | |
| Distribution. Make sure that you set the value of the AXIS2_HOME | |
| variable to match the location into which you extracted the | |
| contents of this release.</p> | |
| <p>Let's look at some different ways to create clients and | |
| services.</p> | |
| <a name="create" id="create"></a> | |
| <h2>Creating Services</h2> | |
| <p>In this section, we'll look at five ways to create a service | |
| based on the StockQuoteService class: deploying Plain Old Java | |
| Objects (POJO), building the service using AXIOM's OMElement, | |
| generating the service using Axis2 Databinding Framework (ADB), | |
| generating the service using XMLBeans, and generating the service | |
| using JiBX.</p> | |
| <a name="deploy" id="deploy"></a> | |
| <h3>Deploying POJOs</h3> | |
| <p>To deploy the service using POJOs (Plain Old Java Objects), | |
| execute the following steps.</p> | |
| <p>Note the directory structure contained at | |
| AXIS2_HOME/samples/quickstart (the services.xml file is | |
| from the first section of this guide):</p> | |
| <pre> | |
| - quickstart | |
| - README.txt | |
| - build.xml | |
| - resources | |
| - META-INF | |
| - services.xml | |
| - src | |
| - samples | |
| - quickstart | |
| - service | |
| - pojo | |
| - StockQuoteService.java | |
| </pre> | |
| <p>Note that you can generate a WSDL from the quickstart directory | |
| by typing:</p> | |
| <pre> | |
| ant generate.wsdl | |
| </pre> | |
| However, creating StockQuoteService.wsdl is optional. It can be the | |
| version generated directly from the Java class, or a customized | |
| version of that file, and that services.xml is the same file | |
| referenced earlier in this document. | |
| <p>Now build the project by typing ant generate.service in the | |
| quickstart directory, which creates the following directory | |
| structure:</p> | |
| <pre> | |
| - quickstart/build/classes | |
| - META-INF | |
| - services.xml | |
| - samples | |
| - quickstart | |
| - service | |
| - pojo | |
| - StockQuoteService.class | |
| </pre> | |
| <p>If you want to deploy the service in an exploded directory | |
| format, rename the classes directory to StockQuoteService, and copy | |
| it to the webapps/axis2/WEB-INF/services directory in your servlet | |
| engine. Otherwise, copy the build/StockQuoteService.aar file to the | |
| webapps/axis2/WEB-INF/services directory in your servlet engine. | |
| Then check to make sure that the service has been properly deployed | |
| by viewing the list of services at:</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/listServices | |
| </pre> | |
| <p>You can also checkout the WSDL at:</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?wsdl | |
| </pre> | |
| <p>And the schema at:</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?xsd | |
| </pre> | |
| <p>Once the URLs are working, quickly test the service. Try | |
| pointing your browser to the following URL:</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService/getPrice?symbol=IBM | |
| </pre> | |
| <p>You will get the following response:</p> | |
| <pre> | |
| <ns:getPriceResponse xmlns:ns="http://pojo.service.quickstart.samples/xsd"><ns:return>42</ns:return></ns:getPriceResponse> | |
| </pre> | |
| <p>If you invoke the update method as,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService/update?symbol=IBM&price=100 | |
| </pre> | |
| and then execute the first getPrice URL, you will see that the | |
| price has got updated. <a name="axiom" id="axiom"></a> | |
| <h3>Building the Service using AXIOM</h3> | |
| <p>To build a service "from scratch" using AXIOM, execute the | |
| following steps.</p> | |
| <p>Note the directory structure contained at | |
| /samples/quickstartaxiom:</p> | |
| <pre> | |
| - quickstartaxiom | |
| - README.txt | |
| - build.xml | |
| - resources | |
| - META-INF | |
| - services.xml | |
| - StockQuoteService.wsdl | |
| - src | |
| - samples | |
| - quickstart | |
| - service | |
| - axiom | |
| - StockQuoteService.java | |
| - clients | |
| - AXIOMClient.java | |
| </pre> | |
| <p>Since AXIOM is a little different, you're going to need a | |
| different services.xml file from the one used for POJO. Define it, | |
| as shown in Code Listing 4.</p> | |
| <p><b>Code Listing 4: The Service Definition File.</b></p> | |
| <pre> | |
| <service name="StockQuoteService" scope="application"> | |
| <description> | |
| Stock Quote Service | |
| </description> | |
| <operation name="getPrice"> | |
| <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> | |
| </operation> | |
| <operation name="update"> | |
| <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> | |
| </operation> | |
| <parameter name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</parameter> | |
| </service> | |
| </pre> | |
| <p>Note that it's almost the same, except that the operations are | |
| explicitly defined in the service.xml file, and the | |
| MessageReceivers are now RawXML.</p> | |
| <p>Now, the above referenced StockQuoteService.java class, a plain | |
| Java class that uses classes from the Axis2 libraries, is defined | |
| as shown in Code Listing 5.</p> | |
| <p><b>Code Listing 5: The StockQuoteService Class using | |
| AXIOM</b></p> | |
| <pre> | |
| package samples.quickstart.service.axiom; | |
| import javax.xml.stream.XMLStreamException; | |
| import org.apache.axiom.om.OMAbstractFactory; | |
| import org.apache.axiom.om.OMElement; | |
| import org.apache.axiom.om.OMFactory; | |
| import org.apache.axiom.om.OMNamespace; | |
| import java.util.HashMap; | |
| public class StockQuoteService { | |
| private HashMap map = new HashMap(); | |
| public OMElement getPrice(OMElement element) throws XMLStreamException { | |
| element.build(); | |
| element.detach(); | |
| OMElement symbolElement = element.getFirstElement(); | |
| String symbol = symbolElement.getText(); | |
| String returnText = "42"; | |
| Double price = (Double) map.get(symbol); | |
| if(price != null){ | |
| returnText = "" + price.doubleValue(); | |
| } | |
| OMFactory fac = OMAbstractFactory.getOMFactory(); | |
| OMNamespace omNs = | |
| fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns"); | |
| OMElement method = fac.createOMElement("getPriceResponse", omNs); | |
| OMElement value = fac.createOMElement("price", omNs); | |
| value.addChild(fac.createOMText(value, returnText)); | |
| method.addChild(value); | |
| return method; | |
| } | |
| public void update(OMElement element) throws XMLStreamException { | |
| element.build(); | |
| element.detach(); | |
| OMElement symbolElement = element.getFirstElement(); | |
| String symbol = symbolElement.getText(); | |
| OMElement priceElement = (OMElement)symbolElement.getNextOMSibling(); | |
| String price = priceElement.getText(); | |
| map.put(symbol, new Double(price)); | |
| } | |
| } | |
| </pre> | |
| <p>Axis2 uses AXIOM, or the AXIs Object Model, a <a href= | |
| "http://www.w3.org/DOM/">DOM</a> (Document Object Model)-like | |
| structure that is based on the StAX API (Streaming API for XML). | |
| Methods that act as services must take as their argument an | |
| OMElement, which represents an XML element that happens, in this | |
| case, to be the payload of the incoming SOAP message. Method | |
| getPrice(OMElement), for example, extracts the contents of the | |
| first child of the payload element, which corresponds to the stock | |
| symbol, and uses this to look up the current price of the stock. | |
| Unless this is an "in only" service, these methods must return an | |
| OMElement, because that becomes the payload of the return SOAP | |
| message.</p> | |
| <p>Now build the project by typing ant generate.service in the | |
| Axis2_HOME/samples/quickstartaxiom directory.</p> | |
| <p>Place the StockQuoteService.aar file in the | |
| webapps/axis2/WEB-INF/services directory of the servlet engine, and | |
| check to make sure that the service has been properly deployed by | |
| viewing the list of services at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/listServices | |
| </pre> | |
| <p>You can also check the custom WSDL at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?wsdl | |
| </pre> | |
| <p>and the schema at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?xsd | |
| </pre> | |
| <a name="adb" id="adb"></a> | |
| <h3>Generating the Service using ADB</h3> | |
| <p>To generate and deploy the service using the Axis2 Databinding | |
| Framework (ADB), execute the following steps.</p> | |
| <p>Generate the skeleton using the WSDL2Java utility by typing the | |
| following in the Axis2_HOME/samples/quickstartadb directory:</p> | |
| <pre> | |
| (Windows) | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.service.adb -d adb -s -ss -sd -ssi -o build\service | |
| (Linux) | |
| $AXIS2_HOME/bin/wsdl2java.sh -uri resources/META-INF/StockQuoteService.wsdl -p samples.quickstart.service.adb -d adb -s -ss -sd -ssi -o build/service | |
| </pre> | |
| <p>Else, simply type ant generate.service in the | |
| Axis2_HOME/samples/quickstartadb directory.</p> | |
| <p>The option -d adb specifies Axis Data Binding (ADB). The -s | |
| switch specifies synchronous or blocking calls only. The -ss switch | |
| creates the server side code (skeleton and related files). The -sd | |
| switch creates a service descriptor (services.xml file). The -ssi | |
| switch creates an interface for the service skeleton. The service | |
| files should now be located at build/service.</p> | |
| <p>If you generated the code by using WSDL2Java directly, next you | |
| have to modify the generated skeleton to implement the service (if | |
| you used "ant generate.service", a completed skeleton will be | |
| copied over the generated one automatically).</p> | |
| <p>Open the | |
| build/service/src/samples/quickstart/adb/service/StockQuoteServiceSkeleton.java | |
| file and modify it to add the functionality of your service to the | |
| generated methods; shown in Code Listing 6.</p> | |
| <p><b>Code Listing 6: Defining the Service Skeleton File</b></p> | |
| <pre> | |
| package samples.quickstart.service.adb; | |
| import samples.quickstart.service.adb.xsd.GetPriceResponse; | |
| import samples.quickstart.service.adb.xsd.Update; | |
| import samples.quickstart.service.adb.xsd.GetPrice; | |
| import java.util.HashMap; | |
| public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface { | |
| private static HashMap map; | |
| static{ map = new HashMap(); } | |
| public void update(Update param0) { | |
| map.put(param0.getSymbol(), new Double(param0.getPrice())); | |
| } | |
| public GetPriceResponse getPrice(GetPrice param1) { | |
| Double price = (Double) map.get(param1.getSymbol()); | |
| double ret = 42; | |
| if(price != null){ | |
| ret = price.doubleValue(); | |
| } | |
| GetPriceResponse res = | |
| new GetPriceResponse(); | |
| res.set_return(ret); | |
| return res; | |
| } | |
| } | |
| </pre> | |
| <p>Now you can build the project by typing the following command in | |
| the build/service directory:</p> | |
| <pre> | |
| ant jar.server | |
| </pre> | |
| <p>If all goes well, you should see the BUILD SUCCESSFUL message in | |
| your window, and the StockQuoteService.aar file in the | |
| build/service/build/lib directory. Copy this file to the | |
| webapps/axis2/WEB-INF/services directory of the servlet engine.</p> | |
| <p>You can check to make sure that the service has been properly | |
| deployed by viewing the list of services at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/listServices | |
| </pre> | |
| <p>You can also check the custom WSDL at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?wsdl | |
| </pre> | |
| <p>and the schema at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?xsd | |
| </pre> | |
| <a name="xmlbeans" id="xmlbeans"></a> | |
| <h3>Generating the Service using XMLBeans</h3> | |
| <p>To generate a service using XMLBeans, execute the following | |
| steps.</p> | |
| <p>Generate the skeleton using the WSDL2Java utility by typing the | |
| following in the Axis2_HOME/samples/quickstartxmlbeans | |
| directory.</p> | |
| <pre> | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.service.xmlbeans -d xmlbeans -s -ss -sd -ssi -o build\service | |
| </pre> | |
| <p>Else simply type ant generate.service in the | |
| Axis2_HOME/samples/quickstartxmlbeans directory.</p> | |
| <p>The option -d xmlbeans specifies XML Beans data binding. The -s | |
| switch specifies synchronous or blocking calls only. The -ss switch | |
| creates the server side code (skeleton and related files). The -sd | |
| switch creates a service descriptor (services.xml file). The -ssi | |
| switch creates an interface for the service skeleton. The service | |
| files should now be located at build/service.</p> | |
| <p>If you generated the code by using WSDL2Java directly, next you | |
| have to modify the generated skeleton to implement the service (if | |
| you used "ant generate.service", a completed skeleton will be | |
| copied over the generated one automatically).</p> | |
| <p>Next open the | |
| build/service/src/samples/quickstart/service/xmlbeans/StockQuoteServiceSkeleton.java | |
| file and modify it to add the functionality of your service to the | |
| generated methods (see Code Listing 7).</p> | |
| <p><b>Code Listing 7: Defining the Service Skeleton</b></p> | |
| <pre> | |
| package samples.quickstart.service.xmlbeans; | |
| import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument; | |
| import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument; | |
| import samples.quickstart.service.xmlbeans.xsd.UpdateDocument; | |
| import java.util.HashMap; | |
| public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface { | |
| private static HashMap map; | |
| static{ map = new HashMap(); } | |
| public void update(UpdateDocument param0) { | |
| <b>map.put(param0.getUpdate().getSymbol(), new Double(param0.getUpdate().getPrice()));</b> | |
| } | |
| public GetPriceResponseDocument getPrice(GetPriceDocument param1) { | |
| <b>Double price = (Double) map.get(param1.getGetPrice().getSymbol()); | |
| double ret = 42; | |
| if(price != null){ | |
| ret = price.doubleValue(); | |
| } | |
| System.err.println(); | |
| GetPriceResponseDocument resDoc = | |
| GetPriceResponseDocument.Factory.newInstance(); | |
| GetPriceResponseDocument.GetPriceResponse res = | |
| resDoc.addNewGetPriceResponse(); | |
| res.setReturn(ret); | |
| return resDoc;</b> | |
| } | |
| } | |
| </pre> | |
| <p>Build the project by typing the following command in the | |
| build/service directory, which contains the build.xml file:</p> | |
| <pre> | |
| ant jar.server | |
| </pre> | |
| <p>If all goes well, you should see the BUILD SUCCESSFUL message in | |
| your window, and the StockQuoteService.aar file in the newly | |
| created build/service/build/lib directory. Copy this file to the | |
| webapps/axis2/WEB-INF/services directory of the servlet engine.</p> | |
| <p>You can check to make sure that the service has been properly | |
| deployed by viewing the list of services at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/listServices | |
| </pre> | |
| <p>You can also check the custom WSDL at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?wsdl | |
| </pre> | |
| <p>and the schema at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?xsd | |
| </pre> | |
| <a name="jibx" id="jibx"></a> | |
| <h3>Generating the Service using JiBX</h3> | |
| <p>To generate and deploy the service using <a href= | |
| "http://www.jibx.org">JiBX data binding</a>, execute the following | |
| steps.</p> | |
| <p>Generate the skeleton using the WSDL2Java utility by typing the | |
| following at a console in the Axis2_HOME/samples/quickstartjibx | |
| directory:</p> | |
| <pre> | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.service.jibx -d jibx -s -ss -sd -ssi -uw -o build\service | |
| </pre> | |
| <p>Else, simply type "ant generate.service" in the | |
| Axis2_HOME/samples/quickstartjibx directory.</p> | |
| <p>The option -d jibx specifies JiBX data binding. The -s switch | |
| specifies synchronous or blocking calls only. The -ss switch | |
| creates the server side code (skeleton and related files). The -sd | |
| switch creates a service descriptor (services.xml file). The -ssi | |
| switch creates an interface for the service skeleton. The -uw | |
| switch unwraps the parameters passed to and from the service | |
| operations in order to create a more natural programming | |
| interface.</p> | |
| <p>After running WSDL2Java, the service files should be located at | |
| build/service. If you generated the code by using WSDL2Java | |
| directly, you need to modify the generated skeleton to implement | |
| the service (if you used "ant generate.service" a completed | |
| skeleton will be copied over the generated one automatically). Open | |
| the | |
| build/service/src/samples/quickstart/service/jibx/StockQuoteServiceSkeleton.java | |
| file and modify it to add the functionality of your service to the | |
| generated methods, as shown in Code Listing 8.</p> | |
| <p><b>Code Listing 8: Defining the Service Skeleton File</b></p> | |
| <pre> | |
| package samples.quickstart.service.jibx; | |
| import java.util.HashMap; | |
| public class StockQuoteServiceSkeleton implements StockQuoteServiceSkeletonInterface { | |
| private HashMap map = new HashMap(); | |
| public void update(String symbol, Double price) { | |
| map.put(symbol, price); | |
| } | |
| public Double getPrice(String symbol) { | |
| Double ret = (Double) map.get(symbol); | |
| if (ret == null) { | |
| ret = new Double(42.0); | |
| } | |
| return ret; | |
| } | |
| } | |
| </pre> | |
| <p>Now you can build the project by typing the following command in | |
| the build/service directory:</p> | |
| <pre> | |
| ant jar.server | |
| </pre> | |
| <p>If all goes well, you should see the BUILD SUCCESSFUL message in | |
| your window, and the StockQuoteService.aar file in the | |
| build/service/build/lib directory. Copy this file to the | |
| webapps/axis2/WEB-INF/services directory of the servlet engine.</p> | |
| <p>You can check to make sure that the service has been properly | |
| deployed by viewing the list of services at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/listServices | |
| </pre> | |
| <p>You can also check the custom WSDL at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?wsdl | |
| </pre> | |
| <p>and the schema at,</p> | |
| <pre> | |
| http://localhost:8080/axis2/services/StockQuoteService?xsd | |
| </pre> | |
| <p>For more information on using JiBX with Axis2, see the <a href= | |
| "jibx/jibx-codegen-integration.html">JiBX code generation | |
| integration</a> details.</p> | |
| <a name="clients" id="clients"></a> | |
| <h2>Creating Clients</h2> | |
| <p>In this section, we'll look at four ways to create clients based | |
| on the StockQuoteService class: building an AXIOM based client, | |
| generating a client using Axis2 Databinding Framework (ADB), | |
| generating a client using XMLBeans, and generating a client using | |
| JiBX.</p> | |
| <a name="clientaxiom" id="clientaxiom"></a> | |
| <h3>Creating a Client with AXIOM</h3> | |
| <p>To build a client using AXIOM, execute the following steps.</p> | |
| <p>Also, note the directory structure shown in the Creating a | |
| service with AXIOM section, duplicated below for completeness.</p> | |
| <pre> | |
| - quickstartaxiom | |
| - README.txt | |
| - build.xml | |
| - resources | |
| - META-INF | |
| - services.xml | |
| - StockQuoteService.wsdl | |
| - src | |
| - samples | |
| - quickstart | |
| - service | |
| - axiom | |
| - StockQuoteService.java | |
| - clients | |
| - AXIOMClient.java | |
| </pre> | |
| <p>The above referenced AXIOMClient.java class is defined as | |
| follows, shown in Code Listing 9.</p> | |
| <p><b>Code Listing 9: The AXIOMClient class using AXIOM</b></p> | |
| <pre> | |
| package samples.quickstart.clients; | |
| import org.apache.axiom.om.OMAbstractFactory; | |
| import org.apache.axiom.om.OMElement; | |
| import org.apache.axiom.om.OMFactory; | |
| import org.apache.axiom.om.OMNamespace; | |
| import org.apache.axis2.Constants; | |
| import org.apache.axis2.addressing.EndpointReference; | |
| import org.apache.axis2.client.Options; | |
| import org.apache.axis2.client.ServiceClient; | |
| public class AXIOMClient { | |
| private static EndpointReference targetEPR = | |
| new EndpointReference("http://localhost:8080/axis2/services/StockQuoteService"); | |
| public static OMElement getPricePayload(String symbol) { | |
| OMFactory fac = OMAbstractFactory.getOMFactory(); | |
| OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns"); | |
| OMElement method = fac.createOMElement("getPrice", omNs); | |
| OMElement value = fac.createOMElement("symbol", omNs); | |
| value.addChild(fac.createOMText(value, symbol)); | |
| method.addChild(value); | |
| return method; | |
| } | |
| public static OMElement updatePayload(String symbol, double price) { | |
| OMFactory fac = OMAbstractFactory.getOMFactory(); | |
| OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns"); | |
| OMElement method = fac.createOMElement("update", omNs); | |
| OMElement value1 = fac.createOMElement("symbol", omNs); | |
| value1.addChild(fac.createOMText(value1, symbol)); | |
| method.addChild(value1); | |
| OMElement value2 = fac.createOMElement("price", omNs); | |
| value2.addChild(fac.createOMText(value2, | |
| Double.toString(price))); | |
| method.addChild(value2); | |
| return method; | |
| } | |
| public static void main(String[] args) { | |
| try { | |
| OMElement getPricePayload = getPricePayload("WSO"); | |
| OMElement updatePayload = updatePayload("WSO", 123.42); | |
| Options options = new Options(); | |
| options.setTo(targetEPR); | |
| options.setTransportInProtocol(Constants.TRANSPORT_HTTP); | |
| ServiceClient sender = new ServiceClient(); | |
| sender.setOptions(options); | |
| sender.fireAndForget(updatePayload); | |
| System.err.println("price updated"); | |
| OMElement result = sender.sendReceive(getPricePayload); | |
| String response = result.getFirstElement().getText(); | |
| System.err.println("Current price of WSO: " + response); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } | |
| </pre> | |
| <p>Axis2 uses AXIOM, or the AXIs Object Model, a DOM (Document | |
| Object Model)-like structure that is based on the StAX API | |
| (Streaming API for XML). Here you setup the payload for the update | |
| and getPrice methods of the service. The payloads are created | |
| similar to how you created the getPriceResponse payload for the | |
| AXIOM service. Then you setup the Options class, and create a | |
| ServiceClient that you'll use to communicate with the service. | |
| First you call the update method, which is a fireAndForget method | |
| that returns nothing. Lastly, you call the getPrice method, and | |
| retrieve the current price from the service and display it.</p> | |
| <p>Now you can build and run the AXIOM client by typing ant | |
| run.client in the Axis2_HOME/samples/quickstartaxiom directory.</p> | |
| <p>You should get the following as output:</p> | |
| <pre> | |
| done | |
| Current price of WSO: 123.42 | |
| </pre> | |
| <a name="clientadb" id="clientadb"></a> | |
| <h3>Generating a Client using ADB</h3> | |
| <p>To build a client using Axis Data Binding (ADB), execute the | |
| following steps.</p> | |
| <p>Generate the client data bindings by typing the following in the | |
| Axis2_HOME/samples/quickstartadb directory:</p> | |
| <pre> | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.clients -d adb -s -o build\client | |
| </pre> | |
| <p>Else, simply type ant generate.client in the | |
| Axis2_HOME/samples/quickstartadb directory.</p> | |
| <p>Next take a look at | |
| quickstartadb/src/samples/quickstart/clients/ADBClient.java, and | |
| see how it's defined in Code Listing 10.</p> | |
| <p><b>Code Listing 10: The ADBClient Class</b></p> | |
| <pre> | |
| package samples.quickstart.clients; | |
| import samples.quickstart.service.adb.StockQuoteServiceStub; | |
| public class ADBClient{ | |
| public static void main(java.lang.String args[]){ | |
| try{ | |
| StockQuoteServiceStub stub = | |
| new StockQuoteServiceStub | |
| ("http://localhost:8080/axis2/services/StockQuoteService"); | |
| getPrice(stub); | |
| update(stub); | |
| getPrice(stub); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* fire and forget */ | |
| public static void update(StockQuoteServiceStub stub){ | |
| try{ | |
| StockQuoteServiceStub.Update req = new StockQuoteServiceStub.Update(); | |
| req.setSymbol ("ABC"); | |
| req.setPrice (42.35); | |
| stub.update(req); | |
| System.err.println("price updated"); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* two way call/receive */ | |
| public static void getPrice(StockQuoteServiceStub stub){ | |
| try{ | |
| StockQuoteServiceStub.GetPrice req = new StockQuoteServiceStub.GetPrice(); | |
| req.setSymbol("ABC"); | |
| StockQuoteServiceStub.GetPriceResponse res = | |
| stub.getPrice(req); | |
| System.err.println(res.get_return()); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| } | |
| </pre> | |
| <p>This class creates a client stub using the Axis Data Bindings | |
| you created. Then it calls the getPrice and update operations on | |
| the Web service. The getPrice method operation creates the GetPrice | |
| payload and sets the symbol to ABC. It then sends the request and | |
| displays the current price. The update method creates an Update | |
| payload, setting the symbol to ABC and the price to 42.35.</p> | |
| <p>Now build and run the client by typing ant run.client in the | |
| Axis2_HOME/samples/quickstartadb directory.</p> | |
| <p>You should get the following as output:</p> | |
| <pre> | |
| 42 | |
| price updated | |
| 42.35 | |
| </pre> | |
| <a name="clientxmlbeans" id="clientxmlbeans"></a> | |
| <h3>Generating a Client using XMLBeans</h3> | |
| <p>To build a client using the XML Beans data bindings, execute the | |
| following steps.</p> | |
| <p>Generate the databings by typing the following in the | |
| xmlbeansClient directory.</p> | |
| <pre> | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.service.xmlbeans -d xmlbeans -s -o build\client | |
| </pre> | |
| <p>Else, simply type ant generate.client in the | |
| Axis2_HOME/samples/quickstartxmlbeans directory.</p> | |
| <p>Note that this creates a client stub code and no server side | |
| code.</p> | |
| <p>Next take a look at | |
| quickstartxmlbeans/src/samples/quickstart/clients/XMLBEANSClient.java, | |
| and see how it's defined in Code Listing 11.</p> | |
| <p><b>Code Listing 11: The XMLBEANSClient class</b></p> | |
| <pre> | |
| package samples.quickstart.clients; | |
| import samples.quickstart.service.xmlbeans.StockQuoteServiceStub; | |
| import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument; | |
| import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument; | |
| import samples.quickstart.service.xmlbeans.xsd.UpdateDocument; | |
| public class XMLBEANSClient{ | |
| public static void main(java.lang.String args[]){ | |
| try{ | |
| StockQuoteServiceStub stub = | |
| new StockQuoteServiceStub | |
| ("http://localhost:8080/axis2/services/StockQuoteService"); | |
| getPrice(stub); | |
| update(stub); | |
| getPrice(stub); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* fire and forget */ | |
| public static void update(StockQuoteServiceStub stub){ | |
| try{ | |
| UpdateDocument reqDoc = UpdateDocument.Factory.newInstance(); | |
| UpdateDocument.Update req = reqDoc.addNewUpdate(); | |
| req.setSymbol ("BCD"); | |
| req.setPrice (42.32); | |
| stub.update(reqDoc); | |
| System.err.println("price updated"); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* two way call/receive */ | |
| public static void getPrice(StockQuoteServiceStub stub){ | |
| try{ | |
| GetPriceDocument reqDoc = GetPriceDocument.Factory.newInstance(); | |
| GetPriceDocument.GetPrice req = reqDoc.addNewGetPrice(); | |
| req.setSymbol("BCD"); | |
| GetPriceResponseDocument res = | |
| stub.getPrice(reqDoc); | |
| System.err.println(res.getGetPriceResponse().getReturn()); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| } | |
| </pre> | |
| <p>This class creates a client stub using the XML Beans data | |
| bindings you created. Then it calls the getPrice and the update | |
| operations on the Web service. The getPrice method operation | |
| creates the GetPriceDocument, its inner GetPrice classes and sets | |
| the symbol to ABC. It then sends the request and retrieves a | |
| GetPriceResponseDocument and displays the current price. The update | |
| method creates an UpdateDocument, updates and sets the symbol to | |
| ABC and price to 42.32, displaying 'done' when complete.</p> | |
| <p>Now build and run the the project by typing ant run.client in | |
| the Axis2_HOME/samples/quickstartxmlbeans directory.</p> | |
| <p>You should get the following as output:</p> | |
| <pre> | |
| 42 | |
| price updated | |
| 42.32 | |
| </pre> | |
| <a name="clientjibx" id="clientjibx"></a> | |
| <h3>Generating a Client using JiBX</h3> | |
| <p>To build a client using JiBX, execute the following steps.</p> | |
| <p>Generate the client stub by typing the following at a console in | |
| the Axis2_HOME/samples/quickstartjibx directory.</p> | |
| <pre> | |
| %AXIS2_HOME%\bin\wsdl2java.bat -uri resources\META-INF\StockQuoteService.wsdl -p samples.quickstart.clients -d jibx -s -uw -o build\client | |
| </pre> | |
| <p>Else, simply type "ant generate.client".</p> | |
| <p>Next take a look at | |
| quickstartjibx/src/samples/quickstart/clients/JiBXClient.java, | |
| shown below in Code Listing 12.</p> | |
| <p><b>Code Listing 12: The JiBXClient class</b></p> | |
| <pre> | |
| package samples.quickstart.clients; | |
| import samples.quickstart.service.jibx.StockQuoteServiceStub; | |
| public class JiBXClient{ | |
| public static void main(java.lang.String args[]){ | |
| try{ | |
| StockQuoteServiceStub stub = | |
| new StockQuoteServiceStub | |
| ("http://localhost:8080/axis2/services/StockQuoteService"); | |
| getPrice(stub); | |
| update(stub); | |
| getPrice(stub); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* fire and forget */ | |
| public static void update(StockQuoteServiceStub stub){ | |
| try{ | |
| stub.update("CDE", new Double(42.35)); | |
| System.err.println("price updated"); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| /* two way call/receive */ | |
| public static void getPrice(StockQuoteServiceStub stub){ | |
| try{ | |
| System.err.println(stub.getPrice("CDE")); | |
| } catch(Exception e){ | |
| e.printStackTrace(); | |
| System.err.println("\n\n\n"); | |
| } | |
| } | |
| } | |
| </pre> | |
| <p>This class uses the created JiBX client stub to access the | |
| getPrice and the update operations on the Web service. The getPrice | |
| method sends a request for the stock "ABC" and displays the current | |
| price. The update method setsnex the price for stock "ABC" to | |
| 42.35.</p> | |
| <p>Now build and run the client by typing "ant run.client" at a | |
| console in the Axis2_HOME/samples/quickstartjibx directory.</p> | |
| <p>You should get the following as output:</p> | |
| <pre> | |
| 42 | |
| price updated | |
| 42.35 | |
| </pre> | |
| <p>For more information on using JiBX with Axis2, see the <a href= | |
| "jibx/jibx-codegen-integration.html">JiBX code generation | |
| integration</a> details.</p> | |
| <a name="summary" id="summary"></a> | |
| <h2>Summary</h2> | |
| <p>Axis2 provides a slick and robust way to get web services up and | |
| running in no time. This guide presented five methods of creating a | |
| service deployable on Axis2, and four methods of creating a client | |
| to communicate with the services. You now have the flexibility to | |
| create Web services using a variety of different technologies.</p> | |
| <a name="furtherstudy" id="furtherstudy"></a> | |
| <h2>For Further Study</h2> | |
| <p><a href="../index.html">Apache Axis2</a></p> | |
| <p><a href="Axis2ArchitectureGuide.html">Axis2 Architecture</a></p> | |
| <p>Introduction to Apache Axis2-<a href= | |
| "http://www.redhat.com/magazine/021jul06/features/apache_axis2/">http://www.redhat.com/magazine/021jul06/features/apache_axis2/</a></p> | |
| </body> | |
| </html> |