Transcript Document

Web Services Programming
Java Web Services Programming
Dickson K.W. Chiu
PhD, SMIEEE
Deitel et al., Java Web Services for Experienced
Programmers
1
Java Web Services Development
Pack (JWSDP)




Now integrated into J2EE 1.4
Provides a convenient all-in-one package
Geared for developers
Contains







JAXP (Java API for XML Processing)
JAX-RPC (Java API for XML-based RPC)
SAAJ (SOAP with Attachments API for Java)
JAXR (Java API for XML Registries)
…
JAXM (Java API for XML Messaging)
See: http://java.sun.com/webservices/
Dickson Chiu 2005
CSIT600c p1-2
JAX-RPC and JAXM




Both based on SOAP with Attachments
For web service programming
Sun recommends JAX-RPC – easier to program
SAAJ / JAXM


Interoperability (e.g. calling other clients)
Non-blocking option
Dickson Chiu 2005
CSIT600c p1-3
JAX-RPC





Java™ API for XML-based RPC
RPC requests and responses represented using
SOAP
Both Web service endpoints and clients use JAXRPC
Services are described using WSDL
Key technology for Web Services in the
upcoming J2EE 1.4 platform
Dickson Chiu 2005
CSIT600c p1-4
Remote Procedure Call (RPC)
RPC, COM, CORBA, RMI:
 Synchronous communication - calling process blocks
until there is a response
 Tightly coupled - client must find recipients and
know method arguments
 Non persistent
Dickson Chiu 2005
CSIT600c p1-5
JAX-RPC Design Goal

Easy to use programming model




Hides all the plumbing – complexity of SOAP
messaging
SOAP and WSDL-based interoperability


Interoperate with any SOAP compliant peers
Extensibility and Modularity


Defining a service
Using a service
Support future versions of XML specification, i.e.,
XMLP (SOAP 1.2 and beyond)
Message handler architecture
Dickson Chiu 2005
CSIT600c p1-6
JAX-RPC Architecture Diagram
Dickson Chiu 2005
CSIT600c p1-7
What happen during
an RPC?








To call a remote procedure, the HelloClient program invokes a method on a
stub, a local object that represents the remote service.
The stub invokes routines in the JAX-RPC runtime system.
The runtime system converts the remote method call into a SOAP message
and then transmits the message as an HTTP request.
When the server receives the HTTP request, the JAX-RPC runtime system
extracts the SOAP message from the request and translates it into a
method call.
The JAX-RPC runtime system invokes the method on the tie object.
The tie object invokes the method on the implementation of the HelloWorld
service.
The runtime system on the server converts the method's response into a
SOAP message and then transmits the message back to the client as an
HTTP response.
On the client, the JAX-RPC runtime system extracts the SOAP message
from the HTTP response and then translates it into a method response for
the HelloClient program.
Dickson Chiu 2005
CSIT600c p1-8
What happen during
an RPC?
Layer
Source
HelloClient Program
HelloWorld Service (definition interface Provided by the application developer
and implementation class)
Stubs
Generated by the wscompile tool, which is
run by the application developer
Ties
Generated by the wsdeploy tool, which is
run by the application developer
JAX-RPC Runtime
System
Included with the Java WSDP
Dickson Chiu 2005
CSIT600c p1-9
Service Description and WSDL
JAX-RPC describes a Web Service as a collection
of remote interfaces and methods
Tools are used to convert between WSDL documents and
sets of Java remote interfaces
WSDL describes a Web Service as a
collection of ports and operations



JAX-RPC service endpoint mapped to WSDL service
description
WSDL enables export of a JAX-RPC service endpoint across
heterogeneous environments
JAX-RPC specifies the standard WSDL<-> Java mapping:



Mapping between service endpoint interface and WSDL definitions
Binding to specific protocol and transport
XML <-> Java data types
Dickson Chiu 2005
CSIT600c p1-10
WSDL Mapping




wsdl:portType mapped
into a Java Interface
(Service Definition
Interface) that extends
java.rmi.Remote
wsdl:operation mapped
into a method of the
Service definition interface
wsdl:message's are
mapped into parameters
of the method
wsdl:type's of
wsdl:message's are
mapped into the types of
the parameters
Dickson Chiu 2005
CSIT600c p1-11
WSDL Mapping Example
<!------------------- WSDL Document ------------------------------------->
<message name=”GetLastTradePriceInput”>
<part name=”tickerSymbol” type=”xsd:string”/>
</message>
<message name=”GetLastTradePriceOutput”?
<part name=”result” type=”xsd:float”/>
</message>
<portType name=”StockQuoteProvider”>
<operation name=”GetLastTradePrice” parameterOrder=”tickerSymbol”>
<input message=”tns:GetLastTradePriceInput”/>
<output message=”tns:GetLastTradePriceOutput”/>
</operation>
</portType>
public interface StockQuoteProvider extends java.rmi.Remote {
float getLastTradePrice(String tickerSymbol)
throws java.rmi.RemoteException;
}
Dickson Chiu 2005
CSIT600c p1-12
Supported Java Type
See J2EE tutorial
 Note: all objects are passed by copy
 Java primitive types
 String, Date, Calendar, BigInteger, BigDecimal
 Multi-dimensional Java arrays
 JAX-RPC value type – classes you’ve written for
your applications, based on the above
 JavaBean Components – also based on the
above
Dickson Chiu 2005
CSIT600c p1-13
Developing a JAX-RPC Web Service
1.
2.
3.
4.
Define service
endpoint
Implement Service
endpoint
Compile code and
generate WSDL
Packaging WAR and
deploy
Dickson Chiu 2005
CSIT600c p1-14
0. Setting the Port
If you do not use the default port 8080, edit:

<INSTALL>/j2eetutorial14/examples/common/build.properties

<INSTALL>/j2eetutorial14/examples/jaxrpc/staticstub/
config-wsdl.xml

<INSTALL>/j2eetutorial14/examples/jaxrpc/
dynamicproxy/config-wsdl.xml

<INSTALL>/j2eetutorial14/examples/jaxrpc/appclient/
config-wsdl.xml

<INSTALL>/j2eetutorial14/examples/jaxrpc/webclient/
config-wsdl.xml

<INSTALL>/j2eetutorial14/examples/jaxrpc/
webclient/web/response.jsp

<INSTALL>/j2eetutorial14/examples/security/
basicauthclient/SecureHello.wsdl

<INSTALL>/j2eetutorial14/examples/security/
mutualauthclient/SecureHello.wsdl
Dickson Chiu 2005
CSIT600c p1-15
1. Service Endpoint Definition

Specified in Service Definition Interface



Could be generated from WSDL document using a tool or
Could be written in Java programming language directly
No assumption about type of client that would use
this service definition interface
package hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloIF extends Remote {
public String sayHello(String s) throws RemoteException;
}
Dickson Chiu 2005
CSIT600c p1-16
2. Service Implementation


Service implementation class is an ordinary Java class
Invocation done inside the servlet container



JAX-RPC defines Servlet-based Endpoint model
Other endpoint models (e.g., stateless session beans) will be
defined in J2EE 1.4 / EJB 2.1
Optional ServiceLifecycle interface for initialization and
destruction callbacks
package hello;
public class HelloImpl implements HelloIF {
public String message = new String("Hello ");
public String sayHello(String s) {
return new String(message + s);
}
}
Dickson Chiu 2005
package hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloIF extends
Remote {
public String sayHello(String s)
throws RemoteException;
}
CSIT600c p1-17
3. Compiling / WSDL generation


Use the ant tool simplifies the job
Compile HelloIF.java and HelloImpl.java, go to the
<INSTALL>/j2eetutorial14/examples/jaxrpc/helloservice/
directory and type the following: ant build



compile-service: compiles HelloIF.java and HelloImpl.java, writing
the class files to the build subdirectory
generate-wsdl: runs wscompile, creating MyHelloService.wsdl and
mapping.xml
Customize wsdl generation with config-interface.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service name="MyHelloService" targetNamespace="urn:Foo"
typeNamespace="urn:Foo" packageName="helloservice">
<interface name="helloservice.HelloIF"/>
</service>
</configuration>
Dickson Chiu 2005
CSIT600c p1-18
4. Packaging the WAR file (i)

Use Deploytool to create a standalone WAR module
Dickson Chiu 2005
CSIT600c p1-19
4. Packaging the WAR file (ii)

Use Deploytool to create a standalone WAR module
Dickson Chiu 2005
CSIT600c p1-20
4. Packaging the WAR file (iii)




Enter context root
Add alias “hello”
Update the endpoint
address to hello (see
previous slide)
Save and Deploy
Dickson Chiu 2005
CSIT600c p1-21
4’. Another way to deploy the WAR file

To create the WAR file that contains
the service code:


asant create-war
Set your admin port, username, and password in
<INSTALL>/j2eetutorial14/examples/common/build.properties.

To deploy the WAR file:


asant deploy-war
Note this may create different
naming
Dickson Chiu 2005
CSIT600c p1-22
JAX-RPC Clients





Independent of how an XML based RPC service (service
endpoint) is implemented on the server side
Generates a Java based client side representation for a
service from WSDL document
Not tied to a specific XML based protocol, transport or any
JAX-RPC implementation specific mechanism
Can use either J2SE or J2EE
3 programming modes:



Static stub-based – least dynamic, easiest to program - you know
everything about the services and pre-generate the stub
Dynamic proxy - call location dynamic (URL/service/name),
information about the service by looking up WSDL document at
run time (but signature of method fixed)
Dynamic invocation interface (DII) – everything dynamic, but
more tedious and more time to set up a call
Dickson Chiu 2005
CSIT600c p1-23
WSDL Generated
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="MyHelloService" targetNamespace="urn:Foo" xmlns:tns="urn:Foo" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types/>
<message name="HelloIF_sayHello">
<part name="String_1" type="xsd:string"/></message>
<message name="HelloIF_sayHelloResponse">
<part name="result" type="xsd:string"/></message>
<portType name="HelloIF">
<operation name="sayHello" parameterOrder="String_1">
<input message="tns:HelloIF_sayHello"/>
<output message="tns:HelloIF_sayHelloResponse"/></operation></portType>
<binding name="HelloIFBinding" type="tns:HelloIF">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="sayHello">
<soap:operation soapAction=""/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="urn:Foo"/></input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded"
namespace="urn:Foo"/></output></operation></binding>
<service name="MyHelloService">
<port name="HelloIFPort" binding="tns:HelloIFBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/></port></service></definitions>
Dickson Chiu 2005
CSIT600c p1-24
WSDL Mapping - binding, port, service



wsdl:service is mapped into an implementation
of javax.xml.rpc.Service interface
JAX-RPC runtime provides the implementation
A javax.xml.rpc.Service class acts as a factory of
either



Instance of a generated stub class
Dynamic proxy for a service port
Instance of the object javax.xml.rpc.Call for the
dynamic invocation of a remote operation on a service
port
Dickson Chiu 2005
CSIT600c p1-25
Static Stub - Client Code
package staticstub;
import javax.xml.rpc.Stub;
Generated by wscompile before
public class HelloClient {
writing this program (i.e., static
private String endpointAddress;
and implementation-specific)
public static void main(String[] args) {
System.out.println("Endpoint address = " + args[0]);
try {
Stub stub = (Stub) (new MyHelloService_Impl().getHelloIFPort());
stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
args[0]);
HelloIF hello = (HelloIF) stub;
System.out.println(hello.sayHello("Duke!"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
// output – “Hello Duke!”
Dickson Chiu 2005
CSIT600c p1-26
Static Stub – build and run

To automate the rest of the steps, go to the
<INSTALL>/j2eetutorial14/examples/jaxrpc/staticstub/
directory and type the following: asant build




generate-stubs: wscompile -gen:client -d build -classpath build
config-wsdl.xml
<configuration xmlns="http://java.sun.com/xml/ns/jaxrpc/ri/config">
<wsdl location="http://localhost:8080/hellojaxrpc/hello?WSDL“
packageName="staticstub"/>
</configuration>
compile-client: compiles src/HelloClient.java and writes the class
file to the build subdirectory.
package-client: packages the files created by the generate-stubs
and compile-client tasks into the dist/client.jar file.
Run the client - asant run
Dickson Chiu 2005
CSIT600c p1-27
Dynamic Proxy-based Client

Client calls a remote procedure through a dynamic
proxy





Client gets information about the service by looking
up its WSDL document at runtime - call location
(URL/service/name)
But the signature (parameters and their types) of the
method is fixed
The Service class that is created during runtime
Similar usage of asant
However, only the service endpoint interface class of
the sample target is used but not the generated stub
Dickson Chiu 2005
CSIT600c p1-28
Example Dynamic Proxy-based Client
package dynamicproxy;
ServiceFactory serviceFactory = ServiceFactory.newInstance();
import java.net.URL;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import dynamicproxy.HelloIF;
Service helloService =
serviceFactory.createService(helloWsdlUrl,
new QName(nameSpaceUri, serviceName));
dynamicproxy.HelloIF myProxy =
(dynamicproxy.HelloIF) helloService.getPort
(new QName(nameSpaceUri,portName),
dynamicproxy.HelloIF.class);
public class HelloClient {
public static void main(String[] args) {
try {
String UrlString = args[0] + "?WSDL";
String nameSpaceUri = "urn:Foo";
String serviceName = "MyHelloService";
String portName = "HelloIFPort";
System.out.println(myProxy.sayHello(“Buzz”));
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("UrlString = " + UrlString);
}
}
URL helloWsdlUrl = new URL(UrlString);
Dickson Chiu 2005
CSIT600c p1-29
Dynamic Invocation Interface (DII) Client



Dynamic invocation of an operation on the target service
endpoint
Enables broker model
Client finds (through search criteria) from a UDDI
directory and invokes a service during runtime through a
broker





Note: the code in the following example does not show the
lookup and simply hardcode the services in strings
Used when service definition interface is not known until
runtime
Set all operation and parameters during runtime
From the Service object create Call object first
Similar usage of asant
Dickson Chiu 2005
CSIT600c p1-30
DII Client Example
package dii;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;
public class HelloClient {
private static String qnameService = "MyHelloService";
private static String qnamePort = "HelloIF";
private static String BODY_NAMESPACE_VALUE = "urn:Foo";
private static String ENCODING_STYLE_PROPERTY =
"javax.xml.rpc.encodingstyle.namespace.uri";
private static String NS_XSD =
"http://www.w3.org/2001/XMLSchema";
private static String URI_ENCODING =
"http://schemas.xmlsoap.org/soap/encoding/";
public static void main(String[] args) {
System.out.println("Endpoint address = " + args[0]);
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new QName(qnameService));
QName port = new QName(qnamePort);
Call call = service.createCall(port);
call.setTargetEndpointAddress(args[0]);
call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY, "");
call.setProperty(ENCODING_STYLE_PROPERTY, URI_ENCODING);
QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
call.setReturnType(QNAME_TYPE_STRING);
call.setOperationName(new QName(BODY_NAMESPACE_VALUE, "sayHello"));
call.addParameter(“String_1”, QNAME_TYPE_STRING,
ParameterMode.IN);
String[] params = { "Murph!" };
String result = (String) call.invoke(params);
System.out.println(result);
} catch (Exception ex) {
ex.printStackTrace();
} } }
try {
Dickson Chiu 2005
CSIT600c p1-31
JAXM



Java API for XML Messaging
Java support for sending and receiving SOAP XML
document oriented messages
Two JAXM API Programming Models



Point-to-point model – simpler
JAXM Provider-based" (like a "messaging server") model supports Asynchronous messaging
Design Goals




Build on SOAP with Attachments
Add support to plug higher-level messaging protocols (e.g.,
ebXML)
Design for easy porting of applications from one container to
another – specifically from web containers to that of J2EE
Don’t attempt to build a full-fledged messaging API (e.g., JMS)
Dickson Chiu 2005
CSIT600c p1-32
JAXM Point-to-Point Model



Synchronous Request-response interaction
Calling process blocks until there is a
response
Connection established directly to the
ultimate recipient


No persistence
can be difficult to scale
Dickson Chiu 2005
CSIT600c p1-33
JAXM Provider Model




Asynchronous (or Synchronous you choose)
Sender is not blocked, Receiver does not have to be
available
Reliable - Message can be stored and forwarded
(routed) until it can be delivered
JAXM Provider works behind the scene
Dickson Chiu 2005
CSIT600c p1-34
JAXM Provider





Offers message routing and reliable messaging as all
messages go through it
Assign message identifiers and keeping track of
messages
JAXM client makes JAXM method calls, and the
provider (working with container) makes everything
happen
JAXM providers are responsible for producing an error
message and sending it to the offending JAXM client
when receiving a malformed message
Responsibility of JAXM application to consume error
messages and take corrective actions
Dickson Chiu 2005
CSIT600c p1-35
JAXM client
Not using JAXM provider





Using JAXM provider
Just a standalone J2SE
 Maintains a connection with
application
JAXM provider, and all
messages go through the
Point to point operation
provider
Establishes a connection
directly with the service  JAXM client deployed in a
web or EJB container
(using a URL)
 MessageDrivenBean
Synchronous only
 JAXMServlet
Request/response
 Send and receive messages
interaction
synchronously or
asynchronously
Dickson Chiu 2005
CSIT600c p1-36
JAXM vs. JMS
Differences

JAXM provider could be
lightweight while JMS provider is
usually heavyweight

JAXM supports standalone mode
while JMS does not

JAXM client is interoperable over
any SOAP compatible client while
JMS client is interoperable only
with other JMS client over the
same messaging system

Delivery endpoint model is
different
Similarities

Both supports Messaging
Provider model



Reliable, secure message
delivery
Routing
Both supports asynchronous
message delivery
Dickson Chiu 2005
CSIT600c p1-37
Using SAAJ API to call a Web Service

Steps
1.
2.
3.
4.
5.
6.



Create SOAP message
Populate SOAP message
Add attachments (optional)
Initialize SOAP connection
Send SOAP message
Analyze response message
Code based on J2EE tutorial p.398 request.java
Library files required:
H:/Sun/Appserver/lib/j2ee.jar;H:/Sun/Appserver/lib/saajimpl.jar;H:\Sun\AppServer\lib\endorsed\xercesImpl.jar;H:\
Sun\AppServer\lib\endorsed\dom.jar;.
Example based on URL:

http://www.mindreef.net/tide/scopeit/start.do?referer=xmethods&url=http
://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl
Dickson Chiu 2005
CSIT600c p1-38
SAAJ Example Code
import javax.xml.soap.*;
import java.util.*;
import java.net.URL;
public class Request {
public static void main(String[] args) {
try {
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnectionFactory.createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPHeader header = message.getSOAPHeader();
SOAPBody body = message.getSOAPBody();
header.detachNode();
Dickson Chiu 2005
CSIT600c p1-39
SAAJ Example Code (2)
Name bodyName = soapFactory.createName( "getQuote", "m",
"urn:xmethods-delayed-quotes");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
Name name = soapFactory.createName("symbol");
SOAPElement symbol = bodyElement.addChildElement(name);
symbol.addTextNode(args[0]);
URL endpoint = new URL("http://64.124.140.30:9090/soap");
SOAPMessage response = connection.call(message, endpoint);
connection.close();
<SOAP-ENV:Envelope xmlns:SOAP-ENV=
response.writeTo(System.out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
"http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:getQuote xmlns:m=" urn:xmethods-delayed-quotes">
<symbol>XXXX</symbol>
</m:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Dickson Chiu 2005
CSIT600c p1-40
SAAJ Result Message
<soap:Envelope
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<n:getQuoteResponse xmlns:n="urn:xmethods-delayed-quotes">
<Result xsi:type="xsd:float">4.15</Result>
</n:getQuoteResponse>
</soap:Body>
</soap:Envelope>
Dickson Chiu 2005
CSIT600c p1-41
Adding Attachment with SAAJ
// We're using a HTTP image repository here
// to get the data for an image
URL url = new URL ("http://images.wombats.com/w.jpg");
// Create a JAF DataHandler with this URL
DataHandler dh = new DataHandler(url);
// Create and Add an AttachmentPart
message.addAttachmentPart(
message.createAttachmentPart(dh));
Dickson Chiu 2005
CSIT600c p1-42
Summary – Calling Web Services in Java

Use JAX-RPC




Static Stub – you know everything about the services
and pre-generate the stub
Dynamic Proxy – call location dynamic
(URL/service/name), information about the service by
looking up WSDL document at run time
(but signature of method fixed)
DII – everything lookup at run time, i.e., call and
parameters prepared at runtime
Send SOAP messages with SAAJ


for most flexibility
target is not RPC
Dickson Chiu 2005
CSIT600c p1-43