Download Soap rpc

Document related concepts
no text concepts found
Transcript
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