Deploying Web Services
with AXIS
Representation and Management
of Data on the Web
1
Web Services
• Web services are methods that a
remote application can call
• The methods are invoked through usual
Web protocols (e.g., HTTP)
• Calling a method:
– Discovery (UDDI)
– Description (WSDL)
– Invocation (SOAP)
2
What is AXIS
• Axis is essentially a SOAP engine – a
framework for constructing SOAP
processors such as clients, servers,
gateways
• AXIS implements the interfaces of
JAX-RPC (remote procedure calls in
Java, using XML)
• AXIS = Apache EXtensible Interaction
System
3
Remote Method Invocation is not a New Idea
• java.rmi has been in Java since Java’s early
versions
• In Java RMI, objects can invoke methods of
objects that reside on a remote computer
(RMI = Remote Method Invokation)
• So, what has been changed:
– Using HTTP and port 80 we can bypass the
firewall
– Using agreed protocols, Java can invoke methods
that were not written in Java (e.g., .NET methods)
and vice versa
– A complex registry procedure has been required in
RMI
4
AXIS Includes
• Axis isn't just a SOAP engine – it also
includes:
– a simple stand-alone server
– a server which plugs into servlet engines such as
Tomcat
– extensive support for the Web Service Description
Language (WSDL)
– emitter tooling that generates Java classes from
WSDL
– a tool for monitoring TCP/IP packets
5
AXIS Installation
• AXIS works inside a Servlet container (e.g.,
Tomcat)
• You should add to your Tomcat libs some jar
files: axis.jar, saaj.jar, wsdl4j.jar, …
• You need to include several jar files in your
CLASSPATH
• This has already been done for you
– The needed CLASSPATH definitions where added
to dbi.cshrc
– The needed jar files were added to
$CATALINA_BASE/shared/lib/
6
Working With AXIS
• AXIS uses Servlets that Tomcat apply
• You should copy the axis directory from
dbi to your webapps directory:
cp –r ~dbi/tomcat/axis $CATALINA_BASE/webapps/
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
The directory that Classes were
you need to copy added for you 7
http://computer-that-run-tomcat:port/axis
Validate installation
View deployed services
8
What We Would Like to Create
• Client applications: applications that
can call a remote service
• Services: methods that can be called
by remote applications
• Service descriptions: WSDL files that
describe our methods
9
Will We Do a Lot of XML Parsing?
• You will not directly read or write SOAP
messages
• Instead, use Java methods that create
request and analyze result
• Use the AxisServlet that actually
includes a SOAP processor
• Code the Client Application and the
Service Application
10
A Client in a Web Service
Request
a WSDL
file
Web
Receive Server
a WSDL
Parse
Returned
WSDL
11
A Client in a Web Service
SOAP
Request
Send
Create SOAP
Request
Web
Receive Server
SOAP
Parse Response
SOAP
Response
12
Creating a Client
1. Create a Service object
2. Create a Call object
3. Set the endpoint URL, i.e., the
destination for the SOAP message
4. Define the operation (method) name of
the Web Service
5. Invoke the desired service, passing in
an array of parameters
13
A Simple Client Example
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class TestClient {
public static void main(String [] args) {
try {
String endpoint =
"http://nagoya.apache.org:5049/axis/services/echo";
Service service = new Service();
Call call = (Call) service.createCall();
14
A Simple Client Example
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/",
"echoString"));
String ret = (String) call.invoke( new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
15
POST http://nagoya.apache.org:5049/axis/services/echo HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.1
Host: nagoya.apache.org:5049
Cache-Control: no-cache
Pragma: no-cache The HTTP Request
SOAPAction: ""
Content-Length: 461
Hello!
16
Example: A Client that
Uses WSDL
• We create an application that calls a
remote Web service
• In our example the remote Web service
produces prime numbers in a given
range
• The service is in URL
http://www.jusufdarmawan.com/wsprimegene
rator.exe/wsdl/IPrimeGenerator
17
The WSDL of the Service
18
String primegenerator(String valstart, String valend)
Defining the function
19
Binding the method as an RPC
20
The Service URL
21
The Client Source Code
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import java.net.URL;
public class PrimeGenerator {
public static void main(String[] argv) {
try {
/* Set the porxy parameters */
System.setProperty("http.proxyHost", "wwwproxy.huji.ac.il");
System.setProperty("http.proxyPort", "8080");
22
/* Set the service parameters */
String defaultNS = null;
String endpoint = null;
URL wsdl = new URL("http://www.jusufdarmawan.com/
wsprimegenerator.exe/wsdl/IPrimeGenerator");
QName serviceName = new
QName("http://www.borland.com/soapServices/",
"IPrimeGeneratorservice");
String method = "primegenerator";
String port = "IPrimeGeneratorPort";
/* Set the service arguments */
String start = "200";
String end = "300";
23
/* Invoke the service */
Service service = new Service(wsdl, serviceName);
Call call = (Call) service.createCall(new
QName(port),
new QName(method));
String value = (String)call.invoke(new Object[] { start, end } );
System.out.println("Primes between " + start +" and " +
end + ": " + value);
} catch (Exception exp) {
exp.printStackTrace(System.err);
}
}
}
24
25
The HTTP Request
POST /wsprimegenerator.exe/soap/IPrimeGenerator HTTP/1.0
content-type:text/xml; charset=utf-8
accept:application/soap+xml, application/dime, multipart/related, text/*
user-agent:Axis/1.1
host:www.jusufdarmawan.com
cache-control:no-cache
pragma:no-cache
soapaction:"urn:UnitIPrimeGenerator-IPrimeGenerator#primegenerator"
content-length:540
-- empty line --
26
200
300
27
The HTTP Response
HTTP/1.0 200 OK
Date: Tue, 08 Jun 2004 20:10:16 GMT
Content-Length: 603
Content-Type: text/xml
Server: Microsoft-IIS/5.0
X-Powered-By: ASP.NET
Content:
Via: 1.1 proxy7 (NetCache NetApp/5.5R4)
28
211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
281, 283, 293
29
Service
• Service()
– the constructor assumes that the caller will set the
appropriate fields by hand rather than getting them
from the WSDL
• Service(java.io.InputStream wsdlInputStream,
QName serviceName)
– Constructs a new Service object for the service in
the WSDL document in the wsdlInputStream and
serviceName parameters
30
Creating a Call
• Call createCall()
– Creates a new Call object with no prefilled data
• Call createCall(QName portName,
QName operationName)
– Creates a new Call object - will prefill as much info
from the WSDL as it can
31
Call
• Used to actually invoke the Web service
• You can invoke the operation
associated with the call using
invoke(…)
• invoke(Object[] params)
– Invokes the operation associated with the
call using the passed in parameters as the
arguments to the method
32
Setting Types
• You can set parameters using the
method addParamether(…)
• You can set the returned type using
setReturnedType(…)
call.addParameter("testParam",
org.apache.axis.Constants.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
33
Creating a Service
• There is a fast and easy way of crating
a service:
1. Create a Java class myClass.java
2. Rename your class to end with jws:
myClass.jws
3. Put the jws file under the directory
$CATALINA_BASE/webapps/axis/
4. That is all. Now you can call the service!
34
Example: a Calculator Service
public class SimpleCalculator {
public int add(int i1, int i2)
{
return i1 + i2;
} We create a Java Class
public int subtract(int i1, int i2)
{
return i1 - i2;
}
}
We rename the file SimpleCalculator.jws
We put the file under webapps/axis
35
http://computer-that-runs-tomcat:port/axis/SimpleCalculator.jws
36
The Client For the Calculator
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;
import javax.xml.rpc.ParameterMode;
public class SimpleCalcClient {
public static void main(String [] args) throws Exception {
String endpoint = "http://mangal.cs.huji.ac.il:8999/axis/SimpleCalculator.jws";
if (args == null || args.length != 3) {
System.err.println("Usage: SimpleCalcClient arg1 arg2");
return;
}
String method = args[0];
if (!(method.equals("add") || method.equals("subtract"))) {
System.err.println("Usage: CalcClient arg1 arg2");
return;
} 37
Integer i1 = new Integer(args[1]);
Integer i2 = new Integer(args[2]);
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( method );
call.addParameter( "op1", XMLType.XSD_INT, ParameterMode.IN );
call.addParameter( "op2", XMLType.XSD_INT, ParameterMode.IN );
call.setReturnType( XMLType.XSD_INT );
Integer ret = (Integer) call.invoke( new Object [] { i1, i2 });
System.out.println("Got result : " + ret);
}
}
38
Tomcat $CATALINA_BASE
webapps shared
friendsnet axis lib classes
WEB-INF
1
SimpleCalculator.jws classes jwsClasses
AxisServlet.class
HTTP Request
2 http://host:8090/axis/SimpleCalculator.jws
39
Tomcat $CATALINA_BASE
webapps shared
friendsnet axis lib classes
WEB-INF
1
SimpleCalculator.jws classes jwsClasses
4
AxisServlet.class SimpleCalculator.class
3 The HTTP Request is “translated” to a request for
http://host:8090/axis/servlet/AxisServlet
The original URL is still known!
40
Tomcat $CATALINA_BASE
webapps shared
friendsnet axis lib classes
WEB-INF
1
SimpleCalculator.jws classes jwsClasses
4
AxisServlet.class SimpleCalculator.class
1. The class SimpleCalculator is compiled and
5 dynamically loaded
2. The SOAP request is parsed and analyzed
HTTP
Response
3. A response is created by the SimpleCalculator
4. The result is wrapped as a SOAP response an returned
to the caller 41
When not to Use jws Files
• When you do not have the Java source
code
• When you don’t want to expose your
code
• When you want to use custom type
mappings
• When you want to use other
configuration options
42
AxisServlet
• Dealing with service calls is done by
AxisServlet
• The following files are mapped to
AxisServlet (in web.xml of the axis
application directory):
– servlet/AxisServlet
– *.jws
– services/*
43
Deploying Services
• When a service is called, the AxisServlet
must know where to look for the application
• Telling where the application can be found is
called "deploying"
• Deploying is a two-step process:
– Create a deployment descriptor file
– Call the java command that deploys the web
application:
java org.apache.axis.client.AdminClient
-p port deploy-file.wsdd
44
Creating a Service
1. Create a Java class
2. Compile the class
3. Put the class under
axis/WEB-INF/classes/the-package-name/
4. Create a deployment descriptor file
mydeploy.wsdd
5. Call the AdminClient Service with the
deployment file as a parameter (in the
computer where Tomcat runs AXIS)
6. You are done and can call the service!
45
Example: A Power Function
• We create a service that computes the
power of two numbers
• We show how to deploy the service
• We demonstrate the service with a
client that calls the service
46
The Service Code
package dbi;
public class PowerService {
public int power(int a, int n) {
return (int)Math.pow(a,n);
}
}
We compile the class and put the file in the right directory
$CATALINA_BASE/webapps/axis/WEB-INF/classes/dbi/PowerService.class
47
Deployment File
We call the file dbideploy.wsdd
java org.apache.axis.client.AdminClient
-p8090 dbideploy.wsdd
After deployment you can call the service 48
A Client that Calls the Power Service
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class PowerClient {
private static final String host = "mangal.cs.huji.ac.il";
private static final int port = 8090;
public static void main(String[] argv) {
try {
int x=2, n=5;
String endpoint = "http://" + host + ":" + port +
"/axis/services/dbiPowerService";
49
call call = (Call) new Service().createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName("power");
Integer value = (Integer)call.invoke(new Object[] {
new Integer(x), new Integer(n)
});
System.out.println(x+"^"+n +"=" + value);
} catch (Exception exp) {
exp.printStackTrace(System.err);
}
} Is it important from which directory I call the client?
} Is it important from which computer I call the client?50
The HTTP Request
POST /axis/services/dbiPowerService HTTP/1.0
content-type:text/xml; charset=utf-8
accept:application/soap+xml, application/dime,
multipart/related, text/*
user-agent:Axis/1.1
host:mangal.cs.huji.ac.il:8090
cache-control:no-cache
pragma:no-cache
soapaction:""
content-length:499
51
2
5
52
HTTP/1.1 200 OK
Content-Type: text/xml;charset=utf-8
Date: Sat, 05 Jun 2004 18:00:02 GMT
The HTTP
Server: Apache-Coyote/1.1
Connection: close
Response
32
53
The WSDL (1)
54
The WSDL (2)
55
The WSDL (3)
56
Deployment File
Required namespaces:
Saying that this is a deployment file
of axis
57
Deployment File
The service is an RPC
The name of the service
(not document)
58
Deployment File
Which methods can be called
The scope of the created object
The class w.r.t. axis/WEB-INF/classes/ 59
The Scope of the Object
• Request (the default): a new object is
created for each request, the service instance
is available for the duration of the request,
regardless of forwarding
• Session: a new object is created for each
new session and the service instance is
available for the entire session
• Application: a singleton shared service
instance is used to serve all invocations
60
Undeployment of Services
We call this file dbiundeploy.wsdd
java org.apache.axis.client.AdminClient
-p8090 dbiundeploy.wsdd
After undeployment you cannot call
On which
the service anymore
computer
to apply? 61
Service Styles
• RPC – a call according to SOAP RPC
conventions
• Document – do not use encoding but maps
XML to Java types
• Wrapped – similar to document, except that
they unwrap the body to individual
parameters
• Message – the services and returns raw XML
in the SOAP envelop, I.e., no type mappings
or data bindings
62
Standard mappings from
WSDL to Java
xsd:base64Binary byte[]
xsd:boolean boolean
xsd:byte byte
xsd:dateTime java.util.Calendar
xsd:decimal java.math.BigDecimal
xsd:double double
xsd:float float
xsd:hexBinary byte[]
xsd:int int
xsd:integer java.math.BigInteger
xsd:long long
xsd:Qname javax.xml.namespace.QName
xsd:short short
xsd:string java.lang.String
63
Note on Parameters
• It must be possible to "serialize" the parameters
that the method invoked receives and returns.
Why?
• The following have default
serialization/deserialization:
– primitive types: int, long, double, etc.
– primitive Objects: Integer, Long, Double, String, etc.
– complex Objects: Vector, Enumeration, Hashtable,
arrays
– easy to use JavaBeans (not discussed here)
64
Remote Exceptions
• When you call a Java method an
exception can be thrown
• Consider a case where a client supplies
a bad argument and an exception
occurs in the server (while handling the
service call)
• What should happen?
65
AXIS Support of WSDL
1. When you deploy a service in Axis, users
may then access your service's URL with a
standard web browser and by appending
"?WSDL" to the end of the URL
2. AXIS provides a "WSDL2Java" tool which
builds Java proxies and skeletons for
services with WSDL descriptions
3. AXIS provides a "Java2WSDL" tool which
builds WSDL from Java classes
66
WSDL2Java Mappings
WSDL clause Java class(es) generated
For each entry in the A java class
type section
A holder if this type is
used as an inout/out parameter
For each portType A java interface
For each binding A stub class
For each service A service interface
A service implementation
(the locator)
67
Using Reflection for Implementing
Web Services
68
How Could a SOAP Processor
be Implemented?
• No, we won't be implementing a SOAP
Processor in this course
• However, it could be implemented using
reflection
• Reflection is a Java mechanism for
discovering the class/methods/fields of an
object
• Reflection allows you to load classes and
invoke methods
69
Simple SOAP Implementation
• In SOAP, the details about the RPC are in an
XML message
• In our Simple SOAP Implementation
example, details will be in parameters of
HTTP request
• We will allow user to invoke any method of
any class, provided that the method only has
String arguments
• All this is to give us an idea of how a SOAP
processor works
70
Getting Invocation Details from Client
(HTML Form)
Class Name:
Method Name:
71
Getting Invocation Details from Client
(HTML Form)
function setArguments() {
num = prompt("Enter the number of arguments to the method", 0);
p = document.getElementById("argumentP");
str = ""
for (i = 0 ; i ";
}
p.innerHTML=str;
info.paramNum.value=num
}
72
Our Simple SOAP Processor
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
import java.lang.reflect.*;
public class SoapImitation extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try{
Class objClass = Class.forName(req.getParameter("class"));
int numParams= Integer.parseInt(req.getParameter("paramNum"));
73
Class[] paramClasses = new Class[numParams];
Object[] paramObjs = new Object[numParams];
for (int i = 0 ; i Method Result" +
result + "");
} catch (Exception e) {
out.println("Error!");
74
} } }
A Class and a Method
package hello;
public class HelloServer {
public String sayHelloTo(String name) {
Return(new String(“Hello “ + name +
“, How are you doing?”);
}
…
}
75
76
77
Scoping
• What did the scoping of the Web
Service correspond to: (request?,
session?, application?)
• How would the implementation differ if
the scoping was different?
78
When Web Application Need to
Share Information
• In your implementation of the friendsnet
Web application you will create
instances of the class FriendsDatabase
• Where is the login for accessing the
database is taken from?
• If you will have a service under axis, will
the service be able to create a
FriendsDatabase instance that includes
the login parameter?
79
A Possible Solution
$CATALINA_BASE
webapps shared
friendsnet axis lib classes
1. Put the FriendsDatabase class under shared
2. Use a static field of FriendsDatabase to hold FriendsDatabase
the login argument
3. The first time a Servlet in friendsnet creates
an instance of FriendsDatabase, this servlet
sets the login
80
4. Now, what about servlets of axis?