Title: Dickson%20K.W.%20Chiu
1Web Services Programming Java Web Services
Programming
- Dickson K.W. Chiu
- PhD, SMIEEE
- Deitel et al., Java Web Services for Experienced
Programmers
2Java Web Services DevelopmentPack (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/
3JAX-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
4JAX-RPC
- Java API for XML-based RPC
- RPC requests and responses represented using SOAP
- Both Web service endpoints and clients use
JAX-RPC - Services are described using WSDL
- Key technology for Web Services in the upcoming
J2EE 1.4 platform
5Remote 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
6JAX-RPC Design Goal
- Easy to use programming model
- Defining a service
- Using a service
- Hides all the plumbing complexity of SOAP
messaging - SOAP and WSDL-based interoperability
- Interoperate with any SOAP compliant peers
- Extensibility and Modularity
- Support future versions of XML specification,
i.e., XMLP (SOAP 1.2 and beyond) - Message handler architecture
7JAX-RPC Architecture Diagram
8What 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.
9What happen during an RPC?
10Service 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 WSDLlt-gt Java
mapping - Mapping between service endpoint interface and
WSDL definitions - Binding to specific protocol and transport
- XML lt-gt Java data types
11WSDL Mapping
- wsdlportType mapped into a Java Interface
(Service Definition Interface) that extends
java.rmi.Remote - wsdloperation mapped into a method of the
Service definition interface - wsdlmessage's are mapped into parameters of the
method - wsdltype's of wsdlmessage's are mapped into the
types of the parameters
12WSDL Mapping Example
- lt!------------------- WSDL Document
-------------------------------------gt - ltmessage nameGetLastTradePriceInputgt
- ltpart nametickerSymbol typexsdstring/gt
- lt/messagegt
- ltmessage nameGetLastTradePriceOutput?
- ltpart nameresult typexsdfloat/gt
- lt/messagegt
- ltportType nameStockQuoteProvidergt
- ltoperation nameGetLastTradePrice
parameterOrdertickerSymbolgt - ltinput messagetnsGetLastTradePriceInput/gt
- ltoutput messagetnsGetLastTradePriceOutput/gt
- lt/operationgt
- lt/portTypegt
- public interface StockQuoteProvider extends
java.rmi.Remote - float getLastTradePrice(String tickerSymbol)
- throws java.rmi.RemoteException
13Supported 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 youve written for
your applications, based on the above - JavaBean Components also based on the above
14Developing a JAX-RPC Web Service
- Define service endpoint
- Implement Service endpoint
- Compile code and generate WSDL
- Packaging WAR and deploy
150. Setting the Port
- If you do not use the default port 8080, edit
- ltINSTALLgt/j2eetutorial14/examples/common/build.pro
perties - ltINSTALLgt/j2eetutorial14/examples/jaxrpc/staticstu
b/config-wsdl.xml - ltINSTALLgt/j2eetutorial14/examples/jaxrpc/dynamicp
roxy/config-wsdl.xml - ltINSTALLgt/j2eetutorial14/examples/jaxrpc/appclient
/config-wsdl.xml - ltINSTALLgt/j2eetutorial14/examples/jaxrpc/webclient
/config-wsdl.xml - ltINSTALLgt/j2eetutorial14/examples/jaxrpc/webclien
t/web/response.jsp - ltINSTALLgt/j2eetutorial14/examples/security/basica
uthclient/SecureHello.wsdl - ltINSTALLgt/j2eetutorial14/examples/security/mutual
authclient/SecureHello.wsdl
161. 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
172. 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)
-
package hello import java.rmi.Remote import
java.rmi.RemoteException public interface
HelloIF extends Remote public String
sayHello(String s) throws RemoteException
183. Compiling / WSDL generation
- Use the ant tool simplifies the job
- Compile HelloIF.java and HelloImpl.java, go to
the ltINSTALLgt/j2eetutorial14/examples/jaxrpc/hello
service/ 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.xm
l - lt?xml version"1.0" encoding"UTF-8"?gt
- ltconfiguration xmlns"http//java.sun.com/xml/ns/j
ax-rpc/ri/config"gt - ltservice name"MyHelloService"
targetNamespace"urnFoo" - typeNamespace"urnFoo" packageName"hellose
rvice"gt - ltinterface name"helloservice.HelloIF"/gt
- lt/servicegt
- lt/configurationgt
194. Packaging the WAR file (i)
- Use Deploytool to create a standalone WAR module
204. Packaging the WAR file (ii)
- Use Deploytool to create a standalone WAR module
214. Packaging the WAR file (iii)
- Enter context root
- Add alias hello
- Update the endpoint address to hello (see
previous slide) - Save and Deploy
224. 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
ltINSTALLgt/j2eetutorial14/examples/common/build.pro
perties. - To deploy the WAR file
- asant deploy-war
- Note this may create different
- naming
23JAX-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
24WSDL Generated
- lt?xml version"1.0" encoding"UTF-8"?gt
- ltdefinitions name"MyHelloService"
targetNamespace"urnFoo" xmlnstns"urnFoo"
xmlns"http//schemas.xmlsoap.org/wsdl/"
xmlnsxsd"http//www.w3.org/2001/XMLSchema"
xmlnssoap"http//schemas.xmlsoap.org/wsdl/soap/"
gt - lttypes/gt
- ltmessage name"HelloIF_sayHello"gt
- ltpart name"String_1" type"xsdstring"/gtlt/mes
sagegt - ltmessage name"HelloIF_sayHelloResponse"gt
- ltpart name"result" type"xsdstring"/gtlt/messa
gegt - ltportType name"HelloIF"gt
- ltoperation name"sayHello" parameterOrder"Str
ing_1"gt - ltinput message"tnsHelloIF_sayHello"/gt
- ltoutput message"tnsHelloIF_sayHelloRespons
e"/gtlt/operationgtlt/portTypegt - ltbinding name"HelloIFBinding"
type"tnsHelloIF"gt - ltsoapbinding transport"http//schemas.xmlsoa
p.org/soap/http" style"rpc"/gt - ltoperation name"sayHello"gt
- ltsoapoperation soapAction""/gt
- ltinputgt
- ltsoapbody encodingStyle"http//schemas.x
mlsoap.org/soap/encoding/" use"encoded"
namespace"urnFoo"/gtlt/inputgt - ltoutputgt
- ltsoapbody encodingStyle"http//schemas.x
mlsoap.org/soap/encoding/" use"encoded"
namespace"urnFoo"/gtlt/outputgtlt/operationgtlt/bindin
ggt
25WSDL Mapping - binding, port, service
- wsdlservice 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
26Static Stub - Client Code
- package staticstub
- import javax.xml.rpc.Stub
- public class HelloClient
- private String endpointAddress
- public static void main(String args)
- System.out.println("Endpoint address "
args0) - try
- Stub stub (Stub) (new
MyHelloService_Impl().getHelloIFPort()) - stub._setProperty(javax.xml.rpc.Stub.E
NDPOINT_ADDRESS_PROPERTY, args0) - HelloIF hello (HelloIF) stub
- System.out.println(hello.sayHello("Duk
e!")) - catch (Exception ex)
- ex.printStackTrace()
-
-
-
- // output Hello Duke!
Generated by wscompile before writing this
program (i.e., static and implementation-specific)
27Static Stub build and run
- To automate the rest of the steps, go to the
ltINSTALLgt/j2eetutorial14/examples/jaxrpc/staticstu
b/ directory and type the following asant build - generate-stubs wscompile -genclient -d build
-classpath build config-wsdl.xml - ltconfiguration xmlns"http//java.sun.com/xml/ns/
jax-rpc/ri/config"gt   - ltwsdl location"http//localhost8080/hello-ja
xrpc/hello?WSDL - packageName"staticstub"/gt
- lt/configurationgt
- 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
28Dynamic 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
29Example Dynamic Proxy-based Client
- package dynamicproxy
- 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
- public class HelloClient
- public static void main(String args)
- try
- String UrlString args0 "?WSDL"
- String nameSpaceUri "urnFoo"
- String serviceName
"MyHelloService" - String portName "HelloIFPort"
- System.out.println("UrlString "
UrlString)
- ServiceFactory serviceFactory
ServiceFactory.newInstance() - Service helloService
- serviceFactory.createService(hello
WsdlUrl, - new QName(nameSpaceUri,
serviceName)) - dynamicproxy.HelloIF myProxy
- (dynamicproxy.HelloIF)
helloService.getPort - (new QName(nameSpaceUri,portName),
- dynamicproxy.HelloIF.class)
- System.out.println(myProxy.sayHello(B
uzz)) - catch (Exception ex)
- ex.printStackTrace()
-
-
-
30Dynamic 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
31DII 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
"urnFoo" - 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)
- ServiceFactory factory
ServiceFactory.newInstance() - Service service factory.createServic
e(new QName(qnameService)) - QName port new QName(qnamePort)
- Call call service.createCall(port)
- call.setTargetEndpointAddress(args0)
- call.setProperty(Call.SOAPACTION_USE_P
ROPERTY, new Boolean(true)) - call.setProperty(Call.SOAPACTION_URI_P
ROPERTY, "") - call.setProperty(ENCODING_STYLE_PROPER
TY, 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()
32JAXM
- 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 - Dont attempt to build a full-fledged messaging
API (e.g., JMS)
33JAXM 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
34JAXM 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
35JAXM 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
36JAXM client
- Not using JAXM provider
- Just a standalone J2SE application
- Point to point operation
- Establishes a connection directly with the
service (using a URL) - Synchronous only
- Request/response interaction
- Using JAXM provider
- Maintains a connection with JAXM provider, and
all messages go through the provider - JAXM client deployed in a web or EJB container
- MessageDrivenBean
- JAXMServlet
- Send and receive messages synchronously or
asynchronously
37JAXM vs. JMS
- Similarities
- Both supports Messaging Provider model
- Reliable, secure message delivery
- Routing
- Both supports asynchronous message delivery
- 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
38Using SAAJ API to call a Web Service
- Steps
- 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.jarH/Sun/Appserver/li
b/saaj-impl.jarH\Sun\AppServer\lib\endorsed\xerc
esImpl.jarH\Sun\AppServer\lib\endorsed\dom.jar.
- Example based on URL
- http//www.mindreef.net/tide/scopeit/start.do?refe
rerxmethodsurlhttp//services.xmethods.net/soap
/urnxmethods-delayed-quotes.wsdl
39SAAJ 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()
40SAAJ Example Code (2)
- Name bodyName soapFactory.createName(
"getQuote", "m", - "urnxmethods-delayed-quotes")
- SOAPBodyElement bodyElement
body.addBodyElement(bodyName) - Name name soapFactory.createName("symbol")
- SOAPElement symbol bodyElement.addChildEle
ment(name) - symbol.addTextNode(args0)
- URL endpoint new URL("http//64.124.140.30
9090/soap") - SOAPMessage response connection.call(messa
ge, endpoint) - connection.close()
- response.writeTo(System.out)
- catch (Exception ex)
- ex.printStackTrace()
-
-
- ltSOAP-ENVEnvelope xmlnsSOAP-ENV
- "http//schemas.xmlsoap.org/soap/envelope/"gt
- ltSOAP-ENVBodygt
- ltmgetQuote xmlnsm" urnxmethods-delayed-quotes
"gt - ltsymbolgtXXXXlt/symbolgt
- lt/mgetQuotegt
- lt/SOAP-ENVBodygt
- lt/SOAP-ENVEnvelopegt
41SAAJ Result Message
- ltsoapEnvelope
- soapencodingStyle"http//schemas.xmlsoap.org/so
ap/encoding/" - xmlnssoap"http//schemas.xmlsoap.org/soap/envel
ope/" xmlnsxsi"http//www.w3.org/2001/XMLSchema-
instance" xmlnsxsd"http//www.w3.org/2001/XMLSch
ema" xmlnssoapenc"http//schemas.xmlsoap.org/soa
p/encoding/"gt - ltsoapBodygt
- ltngetQuoteResponse xmlnsn"urnxmethods-dela
yed-quotes"gt - ltResult xsitype"xsdfloat"gt4.15lt/Resultgt
- lt/ngetQuoteResponsegt
- lt/soapBodygt
- lt/soapEnvelopegt
42Adding 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.jp
g") - // Create a JAF DataHandler with this URL
- DataHandler dh new DataHandler(url)
- // Create and Add an AttachmentPart
- message.addAttachmentPart(
- message.createAttachmentPart(dh))
43Summary 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