Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
SOAP Uses XML to perform RPC (remote procedure call) and has functionality like RMI Soap & Xerces directories • You’ll need to download apache soap and the apache xerces parser. Information on getting soap installed on tomcat is at • C:\soap\soap\docs\body.html • Mail.jar needs to be in tomcat\common\lib Getting started Guide for SOAP installation • http://www.xmethods.net/gettingstarted/ap ache.html • You’ll need to copy the soap.war file into the tomcat webapps directory and fix classpath settings as mentioned elsewhere. (soap.jar, activation.jar, mail.jar are all needed) Classpath- xerces, soap, mail must be in the classpath • My classpath is set to: C:\xerces-j-bin.2.7.0\xerces2_7_0\xercesimpl.jar;C:\xerces-jbin.2.7.0\xerces-2_7_0\resolver.jar;C:\jakartatomcat5.5.10\common\lib\activation.jar;C:\jakartatomcat-5.5.10\common\lib\mail.jar;c:\program files\java\jdk1.5.0_03\bin;c:\program files\java\jdk1.5.0_03\lib;C:\Program Files\Java\jdk1.5.0_03\bin\javax;c:\soap\soap\lib \soap.jar Deploying Apache-SOAP on Tomcat • There are two different ways to actually deploy Apache SOAP on Tomcat: • Method 1: Deploying the web archive. • The Apache SOAP distribution includes a web archive at /soap2_3/webapps/soap.war. Simply drop this web archive into Tomcat's webapps directory (i.e. %tomcat_home%/webapps). If you deploy Apache SOAP into Tomcat in this manner, you will not need to have anything from the /soap-2_3 directory on your server's classpath (the relevant items are included in the web archive). Note: If you copy the web archive into the webapps directory while Tomcat is running, Tomcat will need to be restarted before the Apache SOAP web application can be accessed. • Keep in mind that if you want to replace the deployed Apache SOAP web application with a later version that you will probably have to shut the server down, remove the expanded %tomcat_home%/webapps/soap directory, and replace the %tomcat_home%/webapps/soap.war file with the newer one. Guide for install • • • • • • A Quick-Start Guide for Installing Apache SOAP (version 2.1) Step 1. Install Java Virtual Machine Install Java virtual machine (version 1.1 or later), either as part of the Java SDK installation or the Java Runtime Environment installation. You can download either installation from Sun's Java 2 Homepage Step 2. Install Apache SOAP and Apache Xerces-J (XML Parser) Important Note: It is essential that you run version 1.1.2 or later of Xerces-J. To download the complete packages and learn more about Apache SOAP and Xerces-J, visit the Apache SOAP Homepage and the Apache Xerces-J Homepage. Alternatively, you can download the following quickstart package: quickstart.tar.gz (660K) quickstart.zip (657K) • The quickstart package contains: – – – – soap.jar version 2.1 - contains Apache's SOAP client classes xerces.jar version 1.2 - contains Apache's Xerces-J classes mail.jar and activation.jar - required by Apache SOAP 2.1 Apache license agreement Quickstart I used the mail.jar and activation.jar from Quickstart, but am using Xercesimpl.jar from a download of current xerces parser Xerces-j-bin-2.7.0 Which you can find on the Apache site. Checking soap installation • You’ll know it is working if you can go to your tomcat path/soap (http://localhost:8080/soap/) and get the “what do you want to do” message. Soap message Admin client displays: C:\soap\soap\do cs\guide\inde x.html info about deploying services to Tomcat Soap rpc router servlet displays: SOAP RPC Router Sorry, I don't speak via HTTP GET- you have to use HTTP POST to talk to me. Deployment continued • Copy the class file for your server side service into the jakartatomcat/common/classes directory and or the jar file into the lib directory. • I did not use jar files (The jar file does not seem to be needed.) • You can create a jar for your server class with: jar cf jfname.jar classname.class Client side and Server side classes with NO RETURNS • GetInt passes an int parameter which ReceiveInt receives. Call returns properly and messages are printed on both blackscreen sessions Client side • GetInt – does NOT get an int, just passes one Server and client side passing string • Serverside: import org.apache.soap.*; import org.apache.soap.rpc.*; import org.w3c.dom.*; public class ReturnString { public String returnString(String s) throws Exception { //String message=(String)m.getValue(); String text = "Welcome to SOAP!\nHere is your message: "+s; return (String)text; }} Server and client side passing string C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java GetAString Welcome to SOAP! Here is your message: whatever client side returned C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN> SOAP client as a Java applet • to write a SOAP client as a Java applet. Are there any 'tiny' SOAP client libraries I could use? Consider using SoapRMI for your client. It is 183KB (including full XML parser) and is available here: http://www.extreme.indiana.edu/soap/rmi/downlo ad/. For more details about its design, see: http://www.extreme.indiana.edu/soap/. SOAP Client writing • http://www.xmethods.net/gettingstarted/ap ache.html#writingapacheclients Tomcat & Soap I moved the soap.war file to tomcat/webapps and the jar files to: C:\jakarta\jakartatomcat-5.0.28\common\lib An example • params.addElement (new Parameter ("StudentID", String.class, studentID, null)); Here we add a parameter that should be encoded with a different serializer (in this case, the XML serializer) than the default encoding set at the Call object level. • params.addElement(new Parameter ("StudentProfile", Element.class, profile, Constants.NS_URI_LITERAL_XML)); So it's clear now that we are sending two parameters to the method being invoked - a string, and an XML document. Note that the XML document could have also been sent as a string, in the default SOAP encoding. Now, we add the parameter to the call object: • call.setParams (params); and then invoke the method. • URL url = new URL ("http://www.mySoapRouter.com/soap/servlet/rpcrouter"); Response resp = call.invoke (url, ""); The URL object represents the SOAP endpoint that will be receiving the request. Typically (at least in Apache SOAP server implementations) , a single SOAP endpoint is capable of handling calls to multiple object interfaces and methods. Note that the invocation may throw a SoapException if something goes wrong, so you will need to make provisions to catch the exception. • Next, you will want to check the response to see if a exception was generated at the SOAP protocol level (such an exception would not throw a SoapException fault, which can be thought of as a "lower level" fault). • if (resp.generatedFault()) { Fault fault=resp.getFault(); System.out.println(" Fault code: " + fault.getFaultCode()); System.out.println(" Fault string: "+fault.getFaultString()); } else { Otherwise, the call was successful and a return value can be retrieved. Parameter stores values of class Object, so you will need to downcast the object to expected type for further handling. • Parameter result=resp.getReturnValue(); Object o = result.getValue(); } At this point, the method invocation is complete. Writing RPC Clients Writing clients to access SOAP RPC-based services is fairly straightforward. Apache SOAP provides a clientside API to assist in the construction of the SOAP request, and then to assist in interpreting the response. Conceptually, RPC-based service are relatively easy to understand, because the concepts involved are those which may be found in any procedural based language. To invoke a procedure, you need the name of the procedure and the parameters to pass to it. When the invocation completes, you need to extract any response information from the return value and/or output parameters. RPC Clients The basic steps for creating a client which interacts with a SOAP RPC-based service are as follows: Obtain the interface description of the SOAP service, so that you know what the signatures of the methods that you wish to invoke are. You can either look at a WSDL file (or at some other interface definition format) for the service, or directly at its implementation. Make sure that there are serializers registered for all parameters which you will be sending, and deserializers for all information which you will be receiving back. Parameters must be serialized into/deserialized from XML before they can be transmitted/received, and so Apache SOAP provides a number of predefined serializers/deserializers which are available. If you need to transmit or receive a type which has not been registered, then you will need to write and register your own serializer/deserializer. Create the org.apache.soap.rpc.RPCMessage.Call object. The Apache SOAP Call object is the main interface to the underlying SOAP RPC code Set the target URI into the Call object using the setTargetObjectURI(...) method. Pass in the URN that the service used to identify itself in its deployment descriptor.Set the method name that you wish to invoke into the Call object using the setMethodName(...) method. This must be one of the methods exposed by the service which is identified by the URN given in the previous step. RPC clients Create any Parameter objects necessary for the RPC call and set them into the Call object using the setParams(...) method. Make sure that you have the same number of parameters with the same types as the service is expecting. Also make sure that there are registered serializers/deserializers for the objects which you will be transmitting/receiving. (See step 2.) Execute the Call object's invoke(...) method and capture the Response object which is returned from invoke(...). The invoke(...) method takes in two parameters, the first is a URL which identifies the endpoint at which the service resides (i.e. http://localhost/soap/servlet/rpcrouter) and the second is the value to be placed into the SOAPAction header. Remember that the RPC call is synchronous, and so may take a while to complete. Check the Response object to see if a fault was generated using the generatedFault() method. If a fault was returned, retrieve it using the getFault(...) method, otherwise extract any result or returned parameters using the getReturnValue() and getParams() methods respectively. While most of the providers will only return a result, if you have created your own provider (or obtained one from somewhere else,) it may also return output parameters. Because SOAP is a supposed to be a standard, you should be able to use the clients that you create with the Apache SOAP API to access services running on a different implementations, and vice versa. Writing Message Clients • • • Writing clients to access SOAP message-oriented services requires that you interact with a lower-level set of Apache SOAP APIs than you would otherwise have to if you were writing a SOAP RPC-based client. However, message-oriented services provide you with a finer grain of control over what is actually being transmitted over SOAP. (In fact, the RPC mechanism is built on top of this message-oriented layer.) The basic steps for creating a client which interacts with a SOAP messageoriented service are as follows: Obtain the interface description of the SOAP service, so that you know what the format of the SOAP message should be (i.e. what headers it should have, what the body should look like, etc.) as well as the type of message exchange which will take place. You can either look at a WSDL file (or at some other interface definition format) for the service, or directly at its implementation. Unlike SOAP RPC, there is no predefined message exchange pattern defined, so a messageoriented service may return a SOAP envelope, may return another type of data, or may return nothing at all. • Construct an org.apache.soap.Envelope which contains the information that the SOAP service requires. At the very least, you will need to add an org.apache.soap.Body object to the envelope. You can optionally add headers as well. Note: When the message is received on the server, it will be routed to the proper service by looking at the XML Namespace associated with the first child element in the body, and then to the correct method/function within that service via the name of the element itself. • Create an org.apache.soap.messaging.Message object. If you need to add MIME attachments to your message, then you can use addBodyPart(...) method to do so. If you need to send your message over a transport other than HTTP, then you will need to invoke the setSOAPTransport(...) method. • Invoke the send(...) method on the Message object, providing the URL of the endpoint which is providing the service (i.e. http://localhost/soap/servlet/messagerouter), the actionURI, and your envelope. • If your service is returning data, and assuming that the transport supports two-way interaction, then you need to retrieve the SOAPTransport object from the Message object (assuming that you don't already have a handle to it) by using the getSOAPTransport() method. You can then invoke the receive() method on the SOAPTransport object to retrieve the returned data. If the service is returning a SOAP Envelope, then you can parse the XML and pass the root element to org.apache.soap.Envelope's unmarshall(..) method to allow it to reconstruct a SOAP Envelope object for you. If an error has occurred on the server during the processing of the request, the server will automatically send back a SOAP Envelope with a SOAP Fault in the body describing what went wrong. Compile GetMessage.java C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>javac GetMessage.java -Xlint GetMessage.java:36: warning: [unchecked] unchecked call to addElement(E) as a member of the raw type java.util.Vector parameters.addElement( new Parameter( "message",String.class, message, null ) ); ^ 1 warning C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN> A service routine import java.io.*; import org.w3c.dom.*; import javax.xml.parsers.*; import org.apache.soap.rpc.*; public class SimpleService { public Element getWelcome( ) throws Exception { DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); org.w3c.dom.Element root =null; try{ // get DocumentBuilder DocumentBuilder builder = factory.newDocumentBuilder(); //create root node Document document = builder.newDocument(); root = document.createElement("root"); Comment simpleComment=document.createComment("a comment"); root.appendChild(simpleComment);} catch(ParserConfigurationException pce){pce.printStackTrace();} return root; // return message to the request } }//service Client side user • In notes SOAP online soap page soap envelope to pass data via rpc <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope /" soap:encodingStyle="http://myHost.com/encodings/secu reEncoding" > <soap:Body> <article xmlns="http://www.ibm.com/developer"> <name>Soapbox</name> <url> http://www106.ibm.com/developerworks/library/x-soapbx1.html </url> </article> </soap:Body> </soap:Envelope> the rpc client • Create the SOAP-RPC call • Set up any type mappings for custom parameters • Set the URI of the SOAP service to use • Specify the method to invoke • Specify the encoding to use • Add any parameters to the call • Connect to the SOAP service • Receive and interpret a response a client CDAdder • in notes running the soap rpc from the command line • C:\javaxml2>java javaxml2.CDAdder http://localhost:8080/soap/servlet/rpcrouter "Riding the Midnight Train" "Doc Watson" • Adding CD titled 'Riding the Midnight Train' by 'Doc Watson' • Successful CD Addition CDLister class in notes • another rpc client • running the lister: C:\javaxml2>java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcrouter Listing current CD catalog. 'Riding the Midnight Train' by Doc Watson 'Taproot' by Michael Hedges 'Nickel Creek' by Nickel Creek 'Let it Fall' by Sean Watkins 'Aerial Boundaries' by Michael Hedges custom classes: a CD class: a bean with all getset- methods and a default constructor package javaxml2; public class CD { /** The title of the CD */ private String title; /** The artist performing on the CD */ private String artist; /** The label of the CD */ private String label; public CD( ) { // Default constructor } public CD(String title, String artist, String label) { this.title = title; this.artist = artist; this.label = label; } public String getTitle( ) { return title; } public void setTitle(String title) { this.title = title; } public String getArtist( ) { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getLabel( ) { return label; } public void setLabel(String label) { this.label = label; } public String toString( ) { return "'" + title + "' by " + artist + ", on " + label; } } new service using the CD class in notes • you’ll need to make a new jar file with the new class. • jar files go in the common/lib directory of tomcat • java> jar cvf javaxml2.jar javaxml2/CDCatalog.class javaxml2/CD.class a revised deployment descriptor <isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:cd-catalog" > <isd:provider type="java" scope="Application" methods="addCD getCD list" > <isd:java class="javaxml2.CDCatalog" static="false" /> </isd:provider> <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener > <isd:mappings> <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:x="urn:cd-catalog-demo" qname="x:cd" javaType="javaxml2.CD" java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerial izer" xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSeriali zer"/> </isd:mappings> </isd:service> redeploy dd file • java> java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter CDCatalogDD.xml new CDAdder class using CD class in notes • test run: • C:\javaxml2>java javaxml2.CDAdder http://localhost:8080/soap/servlet/rpcrouter "Tony Rice" "Manzanita" "Sugar Hill" Adding CD titled 'Tony Rice' by 'Manzanita', on the label Sugar Hill Successful CD Addition. better error handling import java.util.Iterator; … if (!response.generatedFault( )) { Parameter returnValue = response.getReturnValue( ); Hashtable catalog = (Hashtable)returnValue.getValue( ); Enumeration e = catalog.keys( ); while (e.hasMoreElements( )) { String title = (String)e.nextElement( ); CD cd = (CD)catalog.get(title); System.out.println(" '" + cd.getTitle( ) + "' by " + cd.getArtist( ) + " on the label " + cd.getLabel( )); } } else { Fault fault = response.getFault( ); System.out.println("Error encountered: " + fault.getFaultString( )); Vector entries = fault.getDetailEntries( ); for (Iterator i = entries.iterator(); i.hasNext( ); ) { org.w3c.dom.Element entry = (org.w3c.dom.Element)i.next( ); System.out.println(entry.getFirstChild().getNodeValue( )); } } from dos window C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN\JAVAXML2>java org.apache.soap.server.ServiceMan agerClient http://localhost:8080/soap/servlet/rpcrouter deploy CDCatalogDD.xml C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>jar cvf javaxml2.jar javaxml2/CDCatalog.class j avaxml2/CD.class added manifest adding: javaxml2/CDCatalog.class(in = 1235) (out= 691)(deflated 44%) adding: javaxml2/CD.class(in = 1049) (out= 507)(deflated 51%) C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java javaxml2.CDAdder http://localhost:8080/soa p/servlet/rpcrouter "Tony Rice" "Manzanita" "Sugar Hill" Adding CD titled 'Tony Rice' by 'Manzanita', on the label Sugar Hill Successful CD Addition. C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN> using rpc soap // Create the parameters Vector params = new Vector( ); params.addElement( new Parameter("flightNumber", Integer.class, flightNumber, null)); params.addElement( new Parameter("numSeats", Integer.class, numSeats, null)); params.addElement( new Parameter("creditCardType", String.class, creditCardType, null)); params.addElement( new Parameter("creditCardNumber", Long.class, creditCardNum, null)); // Create the Call object Call call = new Call( ); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("buyTickets"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); call.setParams(params); // Invoke Response res = call.invoke(new URL("http://rpc.middleearth.com"), ""); // Deal with the response installs and configures • • • • you will need tomcat xerces activation.jar (JAF classes), mail.jar (java.sun.com/products/..) in your classpath • can put soap.jar and other jar files in common/lib of tomcat • soap.war needs to go in webapps directory restart tomcat and check various things checking routers for soap services creating our own service (put in webapps/soap/jspxmlbook/examples) package jspxmlbook.examples; import java.beans.*; public class firstservice extends Object implements java.io.Serializable { public firstservice(){} public String testService(){return ("First Service Test...");} } drop class file into appropriate soap subdirectory (as per package name) before deployment deploy using the soap admin tool example deployment a jsp to list deployed services (I put mine in webapps/root) <%@page contentType="text/html" import ="java.net.*, org.apache.soap.server.*" %> <html> <head><title>list current clients</title></head> <body> listing clients on local server:<br/> <% URL l_url =new URL("http://localhost:8080/soap/servlet/rpcrouter"); ServiceManagerClient l_soap_client=new ServiceManagerClient(l_url); String l_test[]=l_soap_client.list(); for(int i=0;i<l_test.length;i++) {out.println(l_test[i]+"<br/>");} %> </body> </html> running the jsp running our service with a jsp <%@page contentType="text/html" import="java.net.*, org.apache.soap.*, org.apache.soap.rpc.*" %> <% String ls_result=""; Call call=new Call(); call.setTargetObjectURI("urn:jspxmlbook.examples"); call.setMethodName("testService"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); URL url=new URL("http://localhost:8080/soap/servlet/rpcrouter"); Response resp=call.invoke(url,""); if(resp.generatedFault()) { Fault fault=resp.getFault(); ls_result=" Fault code: "+fault.getFaultCode(); ls_result +=" Fault description: "+fault.getFaultString(); } else { Parameter result=resp.getReturnValue(); ls_result= (String) result.getValue(); } %> <html> <head> <title> Running a local Web Service</title></head> <body> the result of the web service call is <br/> <%= ls_result %> </body> </html> a local service jsp A second service: receiving a parameter package jspxmlbook.examples; import java.beans.*; public class paramservice extends Object implements java.io.Serializable { public paramservice(){} public String returnParam(String x) { return ("Second Service Test..."+x);} } a jsp to access the service, note use of Vector class, and Parameter class <%@page contentType="text/html" import="java.net.*, org.apache.soap.*, java.util.*, org.apache.soap.rpc.*" %> <% String ls_result=""; Call call=new Call(); call.setTargetObjectURI("urn:jspxmlbook.examples"); call.setMethodName("returnParam"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector v=new Vector(); String m="Hello down there"; v.add(new Parameter("value",String.class,m,null)); call.setParams(v); URL url=new URL("http://localhost:8080/soap/servlet/rpcrouter"); Response resp=call.invoke(url,""); if(resp.generatedFault()) { Fault fault=resp.getFault(); ls_result=" Fault code: "+fault.getFaultCode(); ls_result +=" Fault description: "+fault.getFaultString();} else { Parameter result=resp.getReturnValue(); ls_result= (String) result.getValue();} %> <html> <head> <title> Running a local Web Service</title></head> <body> the result of the web service call is <br/> <%= ls_result %> </body> </html> register in Soap registry. running the service receiving 2 parameters package jspxmlbook.examples.third; import java.beans.*; public class anotherservice extends Object implements java.io.Serializable { public anotherservice(){} public String pass2Params(String x, int y) { return ("Third Service Test.passed message"+x+" int is"+y);} } passing 2 parameters <% String ls_result=""; Call call=new Call(); call.setTargetObjectURI("urn:jspxmlbook.examples.third"); call.setMethodName("pass2Params"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector v=new Vector(); String message="Some message"; v.add(new Parameter("message",String.class,message,null)); Integer value=new Integer(5); v.add(new Parameter("value",Integer.class,value,null)); call.setParams(v); URL url=new URL("http://localhost:8080/soap/servlet/rpcrouter"); Response resp=call.invoke(url,""); if(resp.generatedFault()) { Fault fault=resp.getFault(); ls_result=" Fault code: "+fault.getFaultCode(); ls_result +=" Fault description: "+fault.getFaultString(); } else { Parameter result=resp.getReturnValue(); ls_result= (String) result.getValue(); } %> passing 2 params to a service a service with multiple methods package jspxmlbook.examples.four; import java.beans.*; import java.util.*; public class multiservice extends Object implements java.io.Serializable { public multiservice(){} public String arithmetic(String x, int y) {int d=Integer.parseInt(x)+y; return ""+d;} public String counter(String s){ Scanner z=new Scanner(s); int c=0; while(z.hasNext()){z.nextInt();c++;} return (" answer="+c);} } jsp accessing multiple methods <title> Running MultiService</title></head> <body> <% String ls_result=""; Call call=new Call(); call.setTargetObjectURI("urn:jspxmlbook.examples.four"); call.setMethodName("arithmetic"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector v=new Vector(); String message="1234"; v.add(new Parameter("message",String.class,message,null)); Integer value=new Integer(5); v.add(new Parameter("value",Integer.class,value,null)); call.setParams(v); URL url=new URL("http://localhost:8080/soap/servlet/rpcrouter"); Response resp=call.invoke(url,""); if(resp.generatedFault()) { Fault fault=resp.getFault(); ls_result=" 1st call Fault code: "+fault.getFaultCode(); ls_result +=" Fault description: "+fault.getFaultString(); } else { Parameter result=resp.getReturnValue(); ls_result= (String) result.getValue(); } %> the result of the web service call is <br/> <%= ls_result %> jsp continued //second method call <% ls_result=""; call=new Call(); call.setTargetObjectURI("urn:jspxmlbook.examples.four"); call.setMethodName("counter"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); v=new Vector(); String string="12 45 67 89 77";//answer should be 5 v.add(new Parameter("string",String.class,string,null)); call.setParams(v); resp=call.invoke(url,""); if(resp.generatedFault()) { Fault fault=resp.getFault(); ls_result="2nd call Fault code: "+fault.getFaultCode(); ls_result +=" Fault description: "+fault.getFaultString(); } else { Parameter result=resp.getReturnValue(); ls_result= (String) result.getValue(); } %> the result of the web service call is <br/> <%= ls_result %> </body> multiple method calls more examples… jar files and deployment descriptors package javaxml2; import java.util.Hashtable; public class CDCatalog { /** The CDs, by title */ private Hashtable catalog; public CDCatalog( ) { catalog = new Hashtable( ); // Seed the catalog catalog.put("Nickel Creek", "Nickel Creek"); catalog.put("Let it Fall", "Sean Watkins"); catalog.put("Aerial Boundaries", "Michael Hedges"); catalog.put("Taproot", "Michael Hedges"); } public void addCD(String title, String artist) { if ((title == null) || (artist == null)) { throw new IllegalArgumentException("Title and artist cannot be null."); } catalog.put(title, artist); } public String getArtist(String title) { if (title == null) { throw new IllegalArgumentException("Title cannot be null."); } // Return the requested CD return (String)catalog.get(title); } public Hashtable list( ) { return catalog; } } deployment descriptor – for use instead of soap admin tool <isd:service xmlns:isd="http://xml.apache.org/xmlsoap/deployment" id="urn:cd-catalog" > <isd:provider type="java" scope="Application" methods="addCD getArtist list" > <isd:java class="javaxml2.CDCatalog" static="false" /> </isd:provider> <isd:faultListener>org.apache.s oap.server.DOMFaultListener</isd:faultListener> </isd:service> the jar file • At this point, you've got a working deployment descriptor and a set of code artifacts to expose, and you can deploy your service. Apache SOAP comes with a utility to do this task, provided you have done the setup work. First, you need a deployment descriptor for your service, which I just talked about. Second, you need to make the classes for your service available to the SOAP server. The best way to do this is to jar up the service class from the last section: • jar cvf javaxml2.jar javaxml2/CDCatalog.class • Take this jar file and drop it into your lib/ directory (or wherever libraries are auto-loaded for your servlet engine), and restart your servlet engine. deployment • With your service class (or classes) accessible by your SOAP server, you can now deploy the service, using Apache SOAP's org.apache.soap.server.ServiceManager utility class: • C:\javaxml2>java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy CDCatalogDD.xml verify it is there… how to undeploy • The first argument is the SOAP server and RPC router servlet, the second is the action to take, and the third is the relevant deployment descriptor. Once this has executed, verify your service was added: • java> java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list • Deployed Services: urn:cd-catalog • At a minimum, this should show any and all services you have available on the server. Finally, you can easily undeploy the service, as long as you know its name: • C:\javaxml2>java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:cd-catalog