| <?xml version="1.0" encoding=""?> | |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
| <head> | |
| <meta http-equiv="content-type" content="" /> | |
| <title>Introducing Axis2</title> | |
| <link href="../css/axis-docs.css" rel="stylesheet" type="text/css" | |
| media="all" /> | |
| </head> | |
| <body> | |
| <a name="buildservices"></a> | |
| <h1>Apache Axis2 User's Guide -Building Services</h1> | |
| <p>Now that you know how to use Axis2 to generate clients from WSDL, this | |
| section digs a little deeper, showing you how to create services, and how to | |
| create both services and clients "from scratch", so to speak.</p> | |
| <ul> | |
| <li><a href="userguide.html#intro">Introducing Axis2</a><br /> | |
| <ul> | |
| <li><a href="userguide.html#whatis">What is Axis2</a></li> | |
| <li><a href="userguide.html#underhood">What's under the hood?</a></li> | |
| <li><a href="userguide.html#handlessoap">How Axis2 handles SOAP | |
| messages</a></li> | |
| <li><a href="userguide.html#distributions">Axis2 distributions</a></li> | |
| <li><a href="userguide.html#sbd">The Axis2 Standard Binary | |
| Distribution</a></li> | |
| <li><a href="userguide.html#hierarchy">Axis2.war Directory | |
| hierarchy</a></li> | |
| <li><a href="userguide.html#docs">Axis2 Documents Distribution</a></li> | |
| <li><a href="userguide.html#clients">Axis2 and clients</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="userguide-installingtesting.html#installingtesting">Installing | |
| and testing client code</a></li> | |
| <li><a href="userguide-introtoservices.html#introservices">Introduction to | |
| Services</a><br /> | |
| <ul> | |
| <li><a href="userguide-introtoservices.html#messageexchange">Message | |
| Exchange Patterns</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="userguide-creatingclients.html#createclients">Creating | |
| Clients</a><br /> | |
| <ul> | |
| <li><a href="userguide-creatingclients.html#choosingclient">Choosing a | |
| Client Generation Method</a></li> | |
| <li><a href="userguide-creatingclients.html#generating">Generating | |
| Clients</a></li> | |
| <li><a href="userguide-creatingclients.html#adb">Axis Data Binding | |
| (ADB)</a></li> | |
| </ul> | |
| </li> | |
| <li><a | |
| href="userguide-buildingservices.html#buildservices"><strong>Building | |
| Services</strong></a><br /> | |
| <ul> | |
| <li><a | |
| href="userguide-buildingservices.html#getcomfortable"><strong>Getting | |
| Comfortable with Available Options</strong></a></li> | |
| <li><a | |
| href="userguide-buildingservices.html#createscratch"><strong>Creating | |
| a service from scratch</strong></a></li> | |
| <li><a | |
| href="userguide-buildingservices.html#deploypojo"><strong>Deploying | |
| Plain Old Java Objects</strong></a></li> | |
| <li><a | |
| href="userguide-buildingservices.html#deployrun"><strong>Deploying | |
| and running an Axis2 service created from WSDL</strong></a></li> | |
| </ul> | |
| </li> | |
| <li><a href="userguide-samples.html">Samples</a></li> | |
| <li><a href="userguide-forfurtherstudy.html">For Further Study</a></li> | |
| </ul> | |
| <p><a name="getcomfortable"></a></p> | |
| <h2>Getting Comfortable with Available Options</h2> | |
| <p>Axis2 provides a number of ways to create a service, such as:</p> | |
| <ul> | |
| <li>Create a service and build it from scratch: In this case, you build | |
| your service class to specifically access AXIOM OMElement objects, then | |
| create the services.xml file and package it up for deployment.</li> | |
| <li>Deploy Plain Old Java Objects (POJOs) as a service.</li> | |
| <li>Generate the service from WSDL: Just as you can generate clients with | |
| WSDL, you can generate the skeleton of a service.</li> | |
| </ul> | |
| <p>Let's look at these three options.</p> | |
| <a name="createscratch"></a> | |
| <h2>Creating a Service From Scratch</h2> | |
| <p>Creating a service from scratch is not the most convenient way to do it, | |
| but it does give you the most control. The process involves several steps.</p> | |
| <p><b>The short story:</b></p> | |
| <ol> | |
| <li>Create the service class, with each operation represented by a method | |
| that takes as its argument a org.apache.axiom.om.OMElement object. (An | |
| OMElement is how the AXIs2 Object Model (AXIOM) represents an XML | |
| element.)</li> | |
| <li>Create the service descriptor, services.xml, which defines the class to | |
| be used by the service and the appropriate message receivers.</li> | |
| <li>Create the .aar file, with the classes in their proper locations based | |
| on package and the services.xml file in the META-INF directory.</li> | |
| <li>Deploy the .aar file by using the <a href="webadminguide.html">Web | |
| Administration application</a> or by copying it to the Axis2 services | |
| directory.</li> | |
| </ol> | |
| <p><b>The long story:</b></p> | |
| <p>Start by creating the service class, a plain Java class that uses classes | |
| from the Axis2 libraries (see Code Listing 8).</p> | |
| <h3>Code Listing 8-Creating the Service Class</h3> | |
| <pre>package org.apache.axis2.axis2userguide; | |
| 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; | |
| public class SampleService { | |
| public OMElement sayHello(OMElement element) | |
| throws XMLStreamException { | |
| element.build(); | |
| element.detach(); | |
| String rootName = element.getLocalName(); | |
| System.out.println("Reading "+rootName+" element"); | |
| OMElement childElement = element.getFirstElement(); | |
| String personToGreet = childElement.getText(); | |
| OMFactory fac = OMAbstractFactory.getOMFactory(); | |
| OMNamespace omNs = fac.createOMNamespace( | |
| "http://example1.org/example1", "example1"); | |
| OMElement method = fac.createOMElement("sayHelloResponse", | |
| omNs); | |
| OMElement value = fac.createOMElement("greeting", omNs); | |
| value.addChild(fac.createOMText(value, "Hello, | |
| "+personToGreet)); | |
| method.addChild(value); | |
| return method; | |
| } | |
| private void ping(){ | |
| } | |
| }</pre> | |
| <p>Make sure to include Axis2 libraries in your class path when compiling the | |
| source.</p> | |
| <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). | |
| Methods that act as services must take as their argument an OMElement, which | |
| represents the payload of the incoming SOAP message. (An OMElement is just | |
| AXIOM's way of representing an XML element, like a DOM Element object.) In | |
| this case, you're extracting the contents of the first child of the payload | |
| element, adding text to it, and using it as content for the return OMElement. | |
| 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>To turn this class into a service, create the service description file, | |
| services.xml, as in Code Listing 9.</p> | |
| <h3>Code Listing 9 - Create the Service Description</h3> | |
| <pre><service name="UserGuideSampleService"> | |
| <description> | |
| This is a sample service created in the Axis2 User's Guide | |
| </description> | |
| <parameter name="ServiceClass" | |
| locked="false">org.apache.axis2.axis2userguide.SampleService | |
| </parameter> | |
| <operation name="sayHello"> | |
| <messageReceiver | |
| class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> | |
| </operation> | |
| <operation name="ping"> | |
| <messageReceiver | |
| class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> | |
| </operation> | |
| </service></pre> | |
| <p>This document defines the service, what it's called by the <a | |
| href="webadminguide.html">Web Administration Application</a>, and the class | |
| used to serve requests. For each operation, it defines the appropriate | |
| message receiver class.</p> | |
| <p>Create a new directory, META-INF, in the main directory for the class. (In | |
| this case, that's the same directory that contains the org directory) and | |
| place the services.xml file in it.</p> | |
| <p>Create the .aar file by typing: jar cvf SampleService.aar ./*</p> | |
| <p>Deploy the SampleService.aar file by using the <a | |
| href="webadminguide.html">Web Administration application</a> or by copying it | |
| to the Axis2 services directory.</p> | |
| <p>Now you can create a client class that accesses the service directly (see | |
| Code Listing 10).</p> | |
| <h3>Code Listing 10 - Create a Client Class that Accesses the Service | |
| Directly</h3> | |
| <pre>package org.apache.axis2.axis2userguide; | |
| 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 org.apache.axis2.addressing.EndpointReference; | |
| import org.apache.axis2.client.Options; | |
| import org.apache.axis2.Constants; | |
| import org.apache.axis2.client.ServiceClient; | |
| public class SampleClient { | |
| private static EndpointReference targetEPR = | |
| new EndpointReference( | |
| "http://localhost:8080/axis2/services/UserGuideSampleService"); | |
| public static OMElement greetUserPayload(String personToGreet) { | |
| OMFactory fac = OMAbstractFactory.getOMFactory(); | |
| OMNamespace omNs = fac.createOMNamespace( | |
| "http://example1.org/example1", "example1"); | |
| OMElement method = fac.createOMElement("sayHello", omNs); | |
| OMElement value = fac.createOMElement("personToGreet", | |
| omNs); | |
| value.addChild(fac.createOMText(value, personToGreet)); | |
| method.addChild(value); | |
| return method; | |
| } | |
| public static void main(String[] args) { | |
| try { | |
| OMElement payload = | |
| SampleClient.greetUserPayload("John"); | |
| Options options = new Options(); | |
| options.setTo(targetEPR); | |
| options.setTransportInProtocol(Constants.TRANSPORT_HTTP); | |
| ServiceClient sender = new ServiceClient(); | |
| sender.setOptions(options); | |
| OMElement result = sender.sendReceive(payload); | |
| String response = result.getFirstElement().getText(); | |
| System.out.println(response); | |
| } catch (Exception e) { //(XMLStreamException e) { | |
| System.out.println(e.toString()); | |
| } | |
| } | |
| }</pre> | |
| <p>This class uses the same technique of sending and receiving OMElements, | |
| but it's also important to note the use of the Options class. This class | |
| enables you to determine properties such as the transport used for the return | |
| message -- the transport used for the outgoing message can be inferred from | |
| the URL of the destination -- and the SOAP version to use. In addition to | |
| providing setter and getter methods of specific properties that affect how | |
| the client interacts with the service, the Options class enables you to | |
| create inheritance relationships between Options objects, so that if a | |
| property is not found in the current Options object used, the client can | |
| check the parent Options object of the current Options object.</p> | |
| <p>Compile and run the above SampleClient.java. Make sure to have all axis2 | |
| libraries in your class path. If all has gone well, 'Hello, John' will be | |
| shown as the output in the console.</p> | |
| <a name="deploypojo"></a> | |
| <h2>Deploying Plain Old Java Objects (POJOs)</h2> | |
| <p>One very easy way to create a Web service is simply to deploy the Java | |
| objects that represent the service. Start with the class, shown in Code | |
| Listing 11.</p> | |
| <h3><b>Code Listing 11 - Creating the Class SampleService</b></h3> | |
| <pre>package org.apache.axis2.axis2userguide; | |
| public class SampleService { | |
| public void doInOnly(){ | |
| return; | |
| } | |
| public String noParameters(){ | |
| return "Hello"; | |
| } | |
| public String twoWayOneParameterEcho(String toEcho){ | |
| return toEcho; | |
| } | |
| public boolean multipleParametersAdd(float price, int itemId, | |
| String description, String itemName){ | |
| //Code to handle the logic | |
| return true; | |
| } | |
| }</pre> | |
| <p>Next, you'll need to tell Axis2 what class corresponds to what Web service | |
| calls. Do this by creating a file called services.xml and adding the | |
| following shown in Code Listing 12.</p> | |
| <h3><b>Code Listing 12 - Creating services.xml</b></h3> | |
| <pre><service name="SampleService" scope="application"> | |
| <description> | |
| Sample Service | |
| </description> | |
| <messageReceivers> | |
| <messageReceiver | |
| mep="http://www.w3.org/2004/08/wsdl/in-only" | |
| class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/> | |
| <messageReceiver | |
| mep="http://www.w3.org/2004/08/wsdl/in-out" | |
| class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> | |
| </messageReceivers> | |
| <parameter name="ServiceClass"> | |
| org.apache.axis2.axis2userguide.SampleService | |
| </parameter> | |
| </service></pre> | |
| <p>This file makes the InOnly and InOut MEPs available to the service and | |
| tells Axis2 which class to call; operations must match method names. In other | |
| words, Axis2 automatically sends a call to the multipleParametersAdd | |
| operation to the | |
| org.apache.axis2.axis2userguide.SampleService.multipleParametersAdd() | |
| method.</p> | |
| <p>Now it's time to create the distribution. Arrange your files in the | |
| following directory structure (see Code Listing 13).</p> | |
| <h3><b>Code Listing 13- Create the Directory Structure for the | |
| Distribution</b></h3> | |
| <pre> - SampleService | |
| - META-INF | |
| - services.xml | |
| - org | |
| - apache | |
| - axis2 | |
| - axis2userguide | |
| - SampleService.class</pre> | |
| <p>Finally, deploy the service by copying the SampleService directory to the | |
| webapps/axis2/WEB-INF/services directory on the servlet engine. You can check to make | |
| sure that it's been properly deployed by checking <a | |
| href="http://<host>:<port>/axis2/services/listServices">http://<host>:<port>/axis2/services/listServices</a>.</p> | |
| <a name="deployrun"></a> | |
| <h2>Deploying and Running an Axis2 Service Created from WSDL</h2> | |
| <p>If you have a WSDL file, you can easily create and deploy a service based | |
| on that description. For example, to create a service based on the same WSDL | |
| file used in the <a href="userguide-creatingclients.html">clients section</a> | |
| of this document, you'd employ the following steps.</p> | |
| <p><b>The short story:</b></p> | |
| <ol> | |
| <li>If you haven't already, <a | |
| href="http://ws.apache.org/axis2/download/1_1/download.cgi#std-bin">download</a> | |
| the Axis2 standard distribution.</li> | |
| <li>Generate the skeleton using the WSDL2Java utility, as in: <br /> | |
| <pre>java org.apache.axis2.wsdl.WSDL2Java -uri file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p org.apache.axis2.axis2userguide -d adb -s -wv 1.1 -ss -sd -ssi</pre> | |
| </li> | |
| <li>Open the *Skeleton.java file and add the functionality of your service | |
| to the generated methods.</li> | |
| <li>Build a service using Ant by typing ant jar.server</li> | |
| <li>Deploy the service by copying the build/lib/*.aar file to | |
| <J2EE_HOME>/webapps/axis2/WEB-INF/services</li> | |
| <li>Check http://<server>:<port>/axis2/services/listServices to | |
| make sure the service has been properly deployed</li> | |
| </ol> | |
| <p><b>The long story:</b></p> | |
| <p>As was the case in generating clients, you will need the <a | |
| href="http://ws.apache.org/axis2/download/1_1/download.cgi#std-bin">Axis2 | |
| Standard Distribution</a>, because the <a | |
| href="http://ws.apache.org/axis2/download/1_1/download.cgi#war">Axis2 War | |
| Distribution</a> does not include the WSDL2Java utility. Once you've got it | |
| downloaded and unpacked, make sure that you set the AXIS2_HOME variable to | |
| point to the location in which you've unpacked it.</p> | |
| <p>Now you are ready to generate the actual service. To keep things neat, | |
| create a new directory and change to it. The WSDL file is the same one | |
| referenced in <a href="userguide-creatingclients#generating.xhtml">Generating | |
| Clients</a> and includes four operations: NoParameters, | |
| TwoWayOneParameterEcho, MultipleParametersAddItem, and DoInOnly. To generate | |
| the service, use the WSDL2Java utility, as in Code Listing 14.</p> | |
| <h3>Code Listing 14 - Using the WSDL2Java Utility to Generate the Service</h3> | |
| <pre>java org.apache.axis2.wsdl.WSDL2Java -uri | |
| file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p | |
| org.apache.axis2.axis2userguide -d adb -s -wv 1.1 -ss -sd</pre> | |
| <p>This statement tells the utility you want to create a service out of the | |
| operations in the file Axis2UserGuide.wsdl, and that the Java classes | |
| generated should be in the org.apache.axis2.axis2userguide package (-p). (You | |
| should see the appropriate directories created.) It also indicates that you | |
| want to use the Axis2 DataBinding Framework, or ADB (-d), to generate only | |
| synchronous, or blocking code (-s), and to generate server-side code (-ss) as | |
| opposed to a client, including the services.xml service descriptor file | |
| (-sd). It also specifies version 1.1 for the WSDL file (-wv). | |
| </p> | |
| <p>At this point, you should see three new items in your chosen directory: | |
| the build.xml file, which includes instructions for Ant, the src directory, | |
| which includes all of the generated classes and stubs, the resources | |
| directory, which includes a regenerated version of the WSDL, and the | |
| services.xml file, which ultimately controls the service's behavior.</p> | |
| <p>You can compile the service at this point, but it doesn't actually do | |
| anything yet. You can solve that problem by opening the | |
| src\org\apache\axis2\axis2userguide\Axis2UserGuideServiceSkeleton.java file | |
| and either editing the code in bold -- make sure you manage parameter numbers | |
| -- or replacing all of the code with the following in Code Listing 15.</p> | |
| <h3>Code Listing 15 - Compiling the Service</h3> | |
| <pre>/** | |
| * Axis2UserGuideServiceSkeleton.java | |
| * | |
| * This file was auto-generated from WSDL | |
| * by the Apache Axis2 version: SNAPSHOT Oct 15, 2006 (11:23:18 | |
| GMT+00:00) | |
| */ | |
| package org.apache.axis2.axis2userguide; | |
| /** | |
| * Axis2UserGuideServiceSkeleton java skeleton for the axisService | |
| */ | |
| public class Axis2UserGuideServiceSkeleton { | |
| /** | |
| * Auto generated method signature | |
| * @param param7 | |
| */ | |
| public org.apache.axis2.axis2userguide.NoParametersResponse | |
| NoParameters | |
| (org.apache.axis2.axis2userguide.NoParametersRequest param7) | |
| { | |
| <b>System.out.println(param7); | |
| NoParametersResponse res = | |
| new NoParametersResponse(); | |
| return res;</b> | |
| } | |
| /** | |
| * Auto generated method signature | |
| * @param param9 | |
| */ | |
| public | |
| org.apache.axis2.axis2userguide.TwoWayOneParameterEchoResponse | |
| TwoWayOneParameterEcho | |
| ( | |
| org.apache.axis2.axis2userguide.TwoWayOneParameterEchoRequest | |
| param9 | |
| ) | |
| { | |
| <b>System.out.println(param9.getEchoString()); | |
| TwoWayOneParameterEchoResponse res = | |
| new TwoWayOneParameterEchoResponse(); | |
| res.setEchoString(param9.getEchoString()); | |
| return res;</b> | |
| } | |
| /** | |
| * Auto generated method signature | |
| * @param param11 | |
| */ | |
| public void DoInOnly | |
| ( | |
| org.apache.axis2.axis2userguide.DoInOnlyRequest param11 | |
| ) | |
| { | |
| <b>System.out.println(param11.getMessageString());</b> | |
| } | |
| /** | |
| * Auto generated method signature | |
| * @param param12 | |
| */ | |
| public | |
| org.apache.axis2.axis2userguide.MultipleParametersAddItemResponse | |
| MultipleParametersAddItem | |
| ( | |
| org.apache.axis2.axis2userguide.MultipleParametersAddItemRequest | |
| param12 | |
| ) | |
| { | |
| <b>System.out.println(param12.getPrice()); | |
| System.out.println(param12.getItemId()); | |
| System.out.println(param12.getDescription()); | |
| System.out.println(param12.getItemName()); | |
| MultipleParametersAddItemResponse res = | |
| new MultipleParametersAddItemResponse(); | |
| res.setSuccessfulAdd(true); | |
| res.setItemId(param12.getItemId()); | |
| return res;</b> | |
| } | |
| }</pre> | |
| <p>As in the case of generating clients, all of these classes, such as | |
| MultipleParametersAddItemRequest and TwoWayOneParameterEchoResponse, are | |
| generated by the utility, and can be found in the same directory as the | |
| skeleton file. They include methods such as setSuccessfulAdd(), which set the | |
| value of the content of an element in the response, and getItemName(), which | |
| retrieve the content of elements in the request.</p> | |
| <p>Save the file and compile it by typing: ant jar.server</p> | |
| <p>If all goes well, you should see the BUILD SUCCESSFUL message in your | |
| window, and the Axis2UserGuideService.aar file in the newly created build/lib | |
| directory.</p> | |
| <p><img alt="The BUILD SUCCESSFUL message in your window" | |
| src="images/fig05.jpg" /></p> | |
| <p>Now you need to deploy the service to the server. To do that, copy the | |
| Axis2UserGuideService.aar file to the WEB-INF/services directory of the | |
| application server. (You also have the option to use the administration | |
| tools. See the <a href="webadminguide.html">Web Administrator's Guide</a> for | |
| more information.)</p> | |
| <p>To verify that the service has been properly deployed, check the list of | |
| services at <a | |
| href="http://<host>:<port>/axis2/services/listServices">http://<host>:<port>/axis2/services/listServices</a>.</p> | |
| <p><img alt="Checking the list of services" src="images/fig06.jpg" /></p> | |
| <p>Now you should be able to access the service using any of the clients | |
| built in the <a href="userguide-creatingclients.html#generating">Generating | |
| Clients</a> document.</p> | |
| <p><strong>See Next Section</strong>- <a | |
| href="userguide-samples.html">Samples</a></p> | |
| </body> | |
| </html> |