Title: Java Training Introduction To Web Services
1Java TrainingIntroduction To Web Services
- Written by Jeff Smith
- (portions borrowed from Apache Axis website)
2The Problem
- Here is the age old IS/IT problemhow can I have
a program (and perhaps multiple instances of it)
running in one centralized place and accessible
by other programs running at other places? - Older Technologies
- Client/Server programming was big in the 90s.
Simplest example of this is a client program that
communicates with a database (perhaps Oracle),
that executes code on a server - CORBA
- RMI
- Now, Web Services
3Web Services Solution
- Web Services are programs that can be invoked by
other pograms (using a well defined protocol)
over a network (e.g., the internet) - Web Services are platform independent,
programming language independent, and allow loose
coupling between software systems - What is the difference between a web application
and a Web Service? - Web application supports user-to-program
interaction - Web Service supports program-to-program
interaction
4Web Services and SOAs -1
- Web Services are the building block of most SOA
(Service Oriented Architectures) - SOAs are loosely coupled systems of independent
software agents - Think of it this waywhere a Java program is a
collection of Java classes that work together in
a single JVM, an SOA system is a collection of
loosely coupled programs (Web Services) that
colloborate over a network - For example, ESRL might create an SOA
5Web Services and SOAs -2
Future ESRL Web Services?
If these web services building blocks were
available, imagine how much easier it would be
to write some new NOAA apps! Moreover,
developers could write their applications in
any language and for any platform Each web
service could be easily tested and
maintained independently
File/Data Finder-searches filesystems, returns
path
WMS (Web Map Service) -given filepath and Lat/Lon
region, returns data as PNG image
WFS (Web Feature Service) -given filepath and
Lat/Lon region, returns data as GML
WCS (Web Coverage Service) -given filepath and
Lat/Lon region, returns binary data
6Web Services Messaging
- How can you send messages to a Web Service?
- Two popular architectures incorporate either SOAP
(Simple Object Access Protocol), which is
something of a misnomer since it isnt really
that simple, and REST (Representational State
Transfer) - Regardless of whether you use SOAP or REST, your
web service will probably be accessed via HTTP
7REST -1
- REST was defined by Roy Fielding in 2000 (Roy
Fielding was a principal author of the HTTP
protocol) - Typical definition--a simple interface for
transmiting data over HTTP without requiring a
messaging layer such as SOAP or session tracking
via Cookies - Key point REST is stateless (like HTTP)
- If a system employs REST, it is sometimes called
RESTful
8REST -2
- REST advantages
- Easily supports caching (improving performance)
- Improves scalability (since state doesnt need to
be maintained, you can cluster serveral RESTful
servers) - Doesnt require software tools to encode/decode
SOAP messages - Simpler to learn than SOAP
9SOAP -1
- From W3C SOAP is a lightweight protocol for
exchanging structured information in a
decentralized, distributed environment. It is an
XML based protocol that consists of three parts
an envelope that defines a framework for
describing what is in a message and how to
process it, a set of encoding rules for
expressing instances of application-defined
datatypes, and a convention for representing
remote procedure calls and responses. - SOAP advantages
- Rigid - type checking, adheres to a contract.
SOAP services are defined by Web Services
Description Language (WSDL) files, which contain
all the information required to make a request. - Development tools ease creation of WSDL
10Apache AXIS
- Apache Axis2 1.2 implements both SOAP and REST
- (dont ask me why they call it Axis2, version
1.2) - You can download Axis from the Apache website
herehttp//ws.apache.org/axis2/ - Or you can download it from the Java Zone
Downloads pagehttp//www-ad.fsl.noaa.gov/ac/javaz
one/Downloads.html - You need Java 1.4
- You need Ant 1.65 or later (to build samples or
Axis2.war file)
11Installing AXIS -1
- Locate the Ant build file (build.xml) inside the
webapp directory (e.g. c\axis2\webapp, or
AXIS2_HOME/webapps folder) - Run the Ant build by executing "ant create.war"
inside the AXIS2_HOME/webapps folder - Copy the newly created axis2.war file to your
Tomcat webapps directory (e.g. c\tomcat5\webapps)
- You can test your AXIS installation by starting
up Tomcat and then typing in this
URLhttp//localhost8080/axis2/
12Installing AXIS -2
- You should see the following at
http//localhost8080/axis2/
13AXIS Clients/Classpath
- To write a Java client program that will invoke
an AXIS web service, you need to add several jars
to your classpath (for example, in Eclipse, for
development purposes) - Note youll find these files in the
axis-install-dir/lib directory
14What is WSDL?
- Web Services Description Language
- WSDL is an XML-formatted language used to
describe a Web service's capabilities as
collections of communication endpoints capable of
exchanging messages. - Basically, it describes what methods are
available, what parameters are passed in, and
what the return type is - WSDL is an integral part of UDDI, an XML-based
worldwide business registry. WSDL is the language
that UDDI uses. WSDL was developed jointly by
Microsoft and IBM - Axis2 does not require WSDL files (although
supplying a WSDL file will allow you to specify
more web service options)
15WSDL and AXIS -1
- Axis supports WSDL in three ways
- With Axis web services, users can access your
service's URL with a standard web browser and by
appending "?WSDL" to the end of the URL, they
will obtain an automatically-generated WSDL
document which describes your service - Axis provides a "WSDL2Java" tool which will build
Java proxies and skeletons for services with WSDL
descriptions - Axis provides a "Java2WSDL" tool which will build
WSDL from Java classes - When you access the web service URL via a
browser, you see a generic message indicating
that the endpoint is an Axis service, and that
you should usually access it using SOAP. - If you tack on "?wsdl" to the end of the URL,
Axis will automatically generate a service
description for the deployed service, and return
it as XML in your browser
16WSDL and AXIS -2
17Simplest Web Service With AXIS -1
- The simplest web service example with AXIS would
be to use Instant Deployment (no WSDL required) - write a single Java class called
HelloWebService.java - make some method(s) public
- copy the .java file to your web application
directory - rename the .java file to .jws
- You can access the WSDL contents of the Web
service as http//localhost8080/mywebapp/HelloWeb
Service.jws?wsdl - Thats all there is to it!
18Simplest Web Service With AXIS -2
- Limitations
- Creating web services this way limits you to
common Java classes such as java.util.Date (an
exact mapping list is available on the Axis Web
site) as method arguments and method return
types. - You cannot use your custom made classes (also
sometimes referred to as Value Objects or VOs) as
method parameters or return types - But if you dont need to return custom objects
(classes) and dont need advanced deployment
options, this is an easy way to deploy a web
service
19Advanced Deployment With AXIS -1
- Advanced deployment permits the use our own
classes as parameter values and return types.
Value Objects or VOs are generally used to
represent the data that needs to be passed on via
methods. - Write your Java Web Service class(s) that can
return your custom data types (classes) - Compile the classes and place the generated
.class files in the WEB-INF/classes folder of
your Web application (or put them in a WAR file)
20Advanced Deployment With AXIS -2
- With Axis1.x, you modify the server-config.wsdd
file and add a service element that will define
your Web service. - ltservice nameWeatherService" provider"javaRPC"
gt - ltparameter name"allowedMethods" value""/gt
- ltparameter name"className
- valuegov.noaa.WeatherFinder"/
gt - ltbeanMapping
- languageSpecificType"javanoaa.WeatherObs
- qname"ns1WeatherObs" xmlnsns1"urnnoaa.g
ov"/gt - lt/servicegt
21Advanced Deployment With AXIS -3
- With Axis2.x, each has a services.xml file which
will inform Axis2 about the service. - ltservicegt
- ltparameter name"ServiceClass
- locked"false"gtSimpleServicelt/parametergt
- ltoperation name"echo"gt
- ltmessageReceiver class"org.apache.axis2.rpc.r
eceivers.RPCMessageReceiver"/gtlt/operationgt - lt/servicegt
- This "service" element encapsulates the
information about a single - service. Within the "service" element there
should be a parameter - specifying the service implementation Java class.
22Java Beans Classes
- If your web service returns a custom bean class
(for example a WeatherObs object), remember to
follow the Java Bean specification - Getters
- Setters
- no argument constructor (you can also define a
constructor that takes arguments, but you MUST
have a no argument constructor as well) - After customizing the server-config.wsdd file,
you can access your Web service's WSDL by using
URL, for example, as - http//localhost8080/mywebapp/services/WeatherSe
rvice?wsdl
23HelloWorld Service -1
- We are going to create a simple HelloWorld
style web service in a directory called
HelloWebService. First, create this directory
structure
24HelloWorld Service -2
- The services.xml file will go in the META-INF
directory
25HelloWorld Service -3
- Place this Java file in the HelloWorldService
directory - public class HelloWorldWebService
-
- /
- This echoHello method will be exposed as the
- operation of the web service
- /
- public String echoHello(String personName)
-
- return("Hello " personName)
-
-
26HelloWorld Service -4
- Place this services.xml file in the META-INF
directory - ltservicegt
- ltparameter name"ServiceClass"
- locked"false"gtHelloWorldWebService
- lt/parametergt
- ltoperation name"echoHello"gt
- ltmessageReceiver
- class"org.apache.axis2.rpc.receivers.RPCMessag
eReceiver"/gt - lt/operationgt
- lt/servicegt
- For more information about services.xml, go here
- http//ws.apache.org/axis2/0_93/axis2config.htmls
ervice
27HelloWorld Service -5
- Were going to create the HelloWorldWebService.aar
file (basically a special jar file). Note the
file name before ".aar" should be the same name
as your web service class - First, CD to the HelloWebService directory and
compile your class like so - javac HelloWorldWebService.java -d temp/
- Second, CD to the temp directory and build your
.aar - jar -cvf HelloWorldWebService.aar
28HelloWorld Service -6
- Now weve got our .aar file
29HelloWorld Service -7
- Deploy your web service by copying it to the
tomcat/webapps/axis2/WEB-INF/services directory
30HelloWorld Service -8
- Restart Tomcat and go to http//localhost8080/axi
s2/services/listServices
31Intro to Stubs -1
- Axis2 includes a WSDL2Java tool to generate the
client side stubs from a WSDL to invoke the web
service. Go to the Axis bin directory (e.g.
C\axis2-1.2\bin) - A Stub class implements the SDI (Service
Definition Interface) - Its name is the binding name with the suffix
"Stub" - It contains the code which turns the method
invocations into SOAP calls using the Axis
Service and Call objects. It stands in as a proxy
for the remote service, letting you call it
exactly as if it were a local object - With stubs, you don't need to deal with the
endpoint URL, namespace, or parameter arrays
which are involved in dynamic invocation via the
Service and Call objects. The stub hides all that
work for you
32Intro to Stubs -2
- SDI is the interface you use to access the
operations on the service. For example, given the
WSDL - ltmessage name"empty"gt
- ltmessage name"AddEntryRequest"gt
- ltpart name"name" type"xsdstring"/gt
- ltpart name"address" type"typensaddress"/gt
- lt/messagegt
- ltportType name"AddressBook"gt
- ltoperation name"addEntry"gt
- ltinput message"tnsAddEntryRequest"/gt
- ltoutput message"tnsempty"/gt
- lt/operationgt
- lt/portTypegt
33Intro to Stubs -3
- WSDL2Java will generate this Java stub
- public interface AddressBook extends
java.rmi.Remote -
- public void addEntry(String name, Address
address) throws java.rmi.RemoteException -
34Intro to Stubs -4
- Normally, a client program would not instantiate
a stub directly. It would instead instantiate a
service locator and call a get method which
returns a stub. This locator is derived from the
service clause in the WSDL. WSDL2Java generates
two objects from a service clause. For example,
given the WSDL - ltservice name"AddressBookService"gt
- ltport name"AddressBook" binding"tnsAddressBoo
kSOAPBinding"gt - ltsoapaddress location"http//localhost8080/
axis/services/AddressBook"/gt - lt/portgt
- lt/servicegt
35Intro to Stubs -5
- WSDL2Java will generate the service interface
- public interface AddressBookService extends
javax.xml.rpc.Service -
- public String getAddressBookAddress()
- public AddressBook getAddressBook() throws
javax.xml.rpc.ServiceException - public AddressBook getAddressBook(URL
portAddress) - throws javax.xml.rpc.ServiceException
-
- WSDL2Java will also generate the locator which
implements this interface - public class AddressBookServiceLocator extends
org.apache.axis.client.Service - implements AddressBookService
-
-
-
36Intro to Stubs -6
- The service interface defines a get method for
each port listed in the service element of the
WSDL. - A typical usage of the stub classes would be as
follows - public class Tester
-
- public static void main(String args) throws
Exception -
- AddressBookService service new
AddressBookServiceLocator() - // Now use the service to get a stub which
implements the SDI. - AddressBook port service.getAddressBook()
- Address address new Address(...)
- port.addEntry("Russell Butek", address)
-
37HelloWorld Client Using Stubs -1
- Under Windows (all of this is one command)
- WSDL2Java.bat -uri http//localhost8080/axis2/ser
vices/ - HelloWorldWebService?wsdl -o c\CoreJava\jeff\Hell
oWebService - Under Linux (all of this is one command)
- sh WSDL2Java.sh -uri http//localhost8080/axis2
/services/ - HelloWorldWebService?wsdl -o /path/to/my/client/co
de/ - You can import the stub file into your client
project to invoke your - web service. For more information, see
- http//ws.apache.org/axis/java/user-guide.html
38HelloWorld Client Using Stubs -2
- Your command window should look something like
this
39HelloWorld Client Using Stubs -3
- You should see some directories and files
created. You can use the Stub class to invoke
the "echoHello" operation of the service. - This is a bit complicatedjust look at those
filenames!
40HelloWorld Client Using Stubs -4
- You could create a new Client.java class which
uses the stub class. For simplicity, place the
Client.java file in the same package as the
generated code (i.e.org.apache.ws.axis2) and save
it along with the other generated code.
41HelloWorld Client Using Stubs -5
package org.apache.ws.axis2 import
org.apache.ws.axis2.HelloWorldWebServiceHelloWorld
WebServiceHttpportStub.EchoHelloResponse public
class Client public static void main(String
args) throws Exception
HelloWorldWebServiceHelloWorldWebServiceHttpportSt
ub stub new HelloWorldWebServiceHelloWo
rldWebServiceHttpportStub() //Create
the request using the stub
HelloWorldWebServiceHelloWorldWebServiceHttpportSt
ub.EchoHello request new
HelloWorldWebServiceHelloWorldWebServiceHttpportSt
ub.EchoHello() request.setParam0("Jeff")
//Invoke the service
EchoHelloResponse response stub.echoHello(reques
t) //dump the web service response to the
console System.out.println("Response "
response.get_return())
42Simple HelloWorld RPC Client -1
- You can build a client by creating a
ServiceClient object, building your SOAP XML
payload, and then sending that SOAP message to
your web service - A simpler way (in my opinion) of building a SOAP
client is to is to write a simple
RPCServiceClient - You dont need to build any stub files this way
(although you also dont get any type checking
that stubs offer) - Well dynamically invoke our web service by
specifying the EndpointRefererence in our client
code - Behind the scenes, the RPCServiceClient is
generating the SOAP (XML) message required to
invoke our web service
43Simple HelloWorld RPC Client -2
44Simple HelloWorld RPC Client -3
import javax.xml.namespace.QName import
org.apache.axis2.AxisFault import
org.apache.axis2.addressing.EndpointReference imp
ort org.apache.axis2.client.Options import
org.apache.axis2.rpc.client.RPCServiceClient pub
lic class HelloWorldClient public static void
main(String args) throws AxisFault
RPCServiceClient serviceClient new
RPCServiceClient() Options options
serviceClient.getOptions()
EndpointReference targetEPR new
EndpointReference(
"http//localhost8080/axis2/services/HelloWorldWe
bService") options.setTo(targetEPR)
45Simple HelloWorld RPC Client -4
//specify http//ws.apache.org/axis2/xsd if
using default package QName opEchoHello new
QName("http//ws.apache.org/axis2/xsd",
"echoHello") Object opEchoHelloArgs
new Object "jeff" Class returnTypes
new Class String.class Object
response serviceClient.invokeBlocking(opE
choHello, opEchoHelloArgs, returnTypes)
String result (String) response0 if
(result null) System.out.println("No
response from web service!") else
System.out.println(result)
46Simple HelloWorld RPC Client -5
- To compile HelloWorldClient.java, youll need to
include the jar files in the Axis2-1.2/lib
directory in your classpath - javac -extdirs C\axis2-1.2\lib\
HelloWorldClient.java - To run HelloWorldClient, youll need to include
these same jars in your runtime classpath like so - java -Djava.ext.dirsC\axis2-1.2\lib\
HelloWorldClient
47QName
- QName represents a Qualified Name as defined in
the XML specifications - it includes a namespace URI (or address)
- and the local part (or method name)
- Go here to learn more about qualified names
- http//www.w3.org/TR/REC-xml-names/ns-qualnames
48Creating A Web Service With Packages -1
- The simple HelloWorld web service we looked at
was in the default package - If you use your own package (a good idea), youll
need to build your .aar file a little differently - Copy your class files directory tree to your temp
directory
49Creating A Web Service With Packages -2
- Delete the .java files from the new copy under
temp (so you are just left with the .class files)
50Creating A Web Service With Packages -3
- Your META-INF directory should still contain your
services.xml file
51Creating A Web Service With Packages -4
- services.xml file should now specify the full
package name - ltservice name"WeatherFinderService"gt
- ltDescriptiongtSearch for weather data by
citylt/Descriptiongt - ltparameter name"ServiceClass
- locked"false"gtgov.noaa.webservice.WeatherFi
nderServicelt/parametergt - ltoperation name"findByCity"gt
- ltmessageReceiver
- class"org.apache.axis2.rpc.receivers.RPC
MessageReceiver"/gt - lt/operationgt
- lt/servicegt
- Note I discovered that Description has to start
with a capital D or else it isnt picked up by
the listServices (a bug they will no doubt fix)
52Creating A Web Service With Packages -5
- QName in your Java client program should now
specify the web service class package too, in
reverse order - //if your web service package is
gov.noaa.webservice - QName opFindByCity new
- QName("http//webservice.noaa.gov/xsd",
"findByCity")
53Creating A Web Service With Packages -6
- Create your JAR file like you did before. CD to
the temp directory and build your .aar - jar -cvf WeatherFinderService.aar
- Next copy your .aar file to the
tomcat/webapps/axis2/WEB-INF/services directory
54Creating A Web Service With Packages -7
- Restart Tomcat and list the services in Axis2
55Development Tips
- If your web service returns a custom object (ie a
java bean), you must implement a no argument
constructor) - Look at the Tomcat console for your debug
messages and error messages. Also look at it to
make sure your web service loads without error!
56HelloWorld Exercise -1
- Create the HelloWorld web service and deploy it
to Tomcat - Write a RPCServiceClient to invoke and test your
web service
57WeatherFinderService Exercise -2a
- Write a WeatherFinderService web service that
looks up weather information for a city (by name)
and returns this information as a custom object - For example, you could have classes called
WeatherFinderService and a Java bean class called
CityWeatherData - When invoked, your web service should read this
information out of a text file
58WeatherFinderService Exercise -2b
Denver,88.5,40.2,36.7 San Antonio,98.5,61.5,16.7 N
ew York,89.5,70.2,76.3 Los Angeles,81.5,44.6,31.1
Cheyenne,78.5,20.2,15.5 Boston,86.5,45.3,56.2 Tes
t your web service with a RPCService client by
having your client request the weather for
Denver, Los Angeles, and Boston and display
the results to the console. Extra Create an ant
script (build.xml) to compile and deploy your web
service
59Axis Generated WSDL -1
QName
method name and parameter
method return type
return type defined
60Axis Generated WSDL -2
SOAP 1.1 binding
SOAP 1.2 binding
61Axis Generated WSDL -3
HTTP binding
62HttpConnection and REST -1
- WSDL 2.0 HTTP binding marries REST with web
services. - So basically, you can design your web services to
support plain old XML (POX) interactions with
services over basic HTTP operations like GET,
POST, PUT, and DELETE - Well create an example that does an HTTP GET to
our WeatherFinderService - You can think of it this way--since our web
service is accessible via simple http, we can
invoke it by writing a client that just retrieves
the XML from a URL - Note this client could be written in any language
and could access our web service over an
intranet, or from across the world via the
internet
63HttpConnection and REST -2
- As we saw in the WSDL that Axis2 generated, it
automatically creates an HTTP binding for us,
making it easy for us to write a simple, RESTful
client - To learn more about defining HTTP bindings in
WSDL, there is a good article on IBM
DeveloperWorks - http//www.ibm.com/developerworks/webservices/libr
ary/ws-rest1/ - The next slide shows you how to invoke your web
service using HTTP binding and a web browser
64HttpConnection and REST -3
You can invoke your web service using HTTP GET
(no SOAP message required). The response will be
XML
web service response as XML
65Http Connections in Java
- A little refresher example on connecting to URLs
in Java - URL url new URL(http//www.wrfportal.org/index.
html) - URLConnection urlCon url.openConnection()
//connect to this URL - //use the urlCons InputStream to create a
BufferedReader - InputStream inputStream urlCon.getInputStream()
- InputStreamReader isr new InputStreamReader(inpu
tStream) - BufferedReader bufReader new BufferedReader(isr)
- String line null
- while ((line bufReader.readLine()) ! null)
//read lines from URL until null - System.out.println(line "\n")
- bufReader.close() //close the BufferedReader
for this urlCon InputStream
66XML -1
- Many web services return data in the form of XML
- There are a number of ways to encode and decode
XML documents in Java - SAX (Simple API for XML) enables you to process a
document while it is being read, so your program
doesnt have to wait until the entire document is
received before starting to process it - With DOM (Document Object Model), data is stored
in a tree-like structure (object) which mirrors
the structure of the XML document. DOM can be a
bit simpler conceptually (since it isnt event
driven like SAX), and is more flexible because
your Java program can easily modify data in the
tree. JDOM is an implementation of DOM for Java
67XML -2
- Use SAX when you need to process huge XML files
and want to conserve memory. - SAX also tends to be faster
- Use JDOM when the XML is relatively small and/or
you need to modify it at run time - JDOM is easy to use
- JDOM implementation is available
herehttp//www.jdom.org/ - Add jdom.jar and xerces.jar to your classpath
(you can download them from the Java Zone
downloads page) - Next slide shows an example using JDOM
68XML -3
import java.io. import org.jdom. import
org.jdom.input. import org.jdom.output.
public class XMLPrinter public static
void main(String args) throws Exception //
Assume filename argument String filename
args0 try // Build the document with
SAX and Xerces SAXBuilder builder new
SAXBuilder() Document doc
builder.build(new File(filename)) // Output
to console, use standard formatter
XMLOutputter fmt new XMLOutputter()
fmt.output(doc, System.out)
69XML -4
This code iterates through an incoming stream of
XML from our WeatherFinderService and dumps
results to the console SAXBuilder builder new
SAXBuilder() Document doc builder.build(inputS
tream) Element rootElement
doc.getRootElement() //first element is
return value Element returnElement
(Element)rootElement.getChildren().get(0)
List namedChildren returnElement.getChildren()
for (Iterator it namedChildren.iterator()
it.hasNext() ) Element element
(Element)it.next() System.out.println(element
.getName() "" element.getValue())
70XML -5
Console Results cityNameDenver cloudCoverPct36
.7 relativeHumidityPct40.2 temperatureDegFah88.5
71RESTful Web Service Client Exercise
- Create a simple Java class that connects to your
WeatherFinderService using HTTP - Issue a request to your web service for the
weather in several cities, and display the
results in the system console - You can either dump the XML as simple text, or
you can use JDOM to build a DOM object
representing your XML
72Summary -1
- Weve just scratched the surface of web service
possibilities and technologies - It is fairly easy to create an Axis2 web service
by writing a POJO (plain old Java class) with
public method(s) and which returns values as Java
beans - define a services.xml file
- Archive it as an .aar (Axis archive file)
- Since Axis2 supports SOAP and REST (as well as
HTTP bindings), we can write clients using stubs,
RPCs, or by writing simple HttpConnection clients - There are other Java XML libraries such as JAXP
that offer more advanced capabilities