43
1 Web Services Programming Java Web Services Programming Dickson K.W. Chiu PhD, SMIEEE Deitel et al., Java Web Services for Experience d Programmers

1 Web Services Programming Java Web Services Programming Dickson K.W. Chiu PhD, SMIEEE Deitel et al., Java Web Services for Experienced Programmers

  • View
    246

  • Download
    4

Embed Size (px)

Citation preview

1

Web Services ProgrammingJava Web Services Programming

Dickson K.W. ChiuPhD, SMIEEE

Deitel et al., Java Web Services for Experienced Programmers

Dickson Chiu 2005 CSIT600c p1-2

Java 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/

Dickson Chiu 2005 CSIT600c p1-3

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-4

JAX-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

Dickson Chiu 2005 CSIT600c p1-5

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-6

JAX-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

Dickson Chiu 2005 CSIT600c p1-7

JAX-RPC Architecture Diagram

Dickson Chiu 2005 CSIT600c p1-8

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-9

What happen during an RPC?

Layer Source

HelloClient Program HelloWorld Service (definition interface and implementation class)

Provided by the application developer

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-10

Service Description and WSDL

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

JAX-RPC describes a Web Service as a collectionof remote interfaces and methods

WSDL describes a Web Service as acollection of ports and operations

Tools are used to convert between WSDL documents and sets of Java remote interfaces

Dickson Chiu 2005 CSIT600c p1-11

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-12

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-13

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-14

Developing a JAX-RPC Web Service

1. Define service endpoint

2. Implement Service endpoint

3. Compile code and generate WSDL

4. Packaging WAR and deploy

Dickson Chiu 2005 CSIT600c p1-15

0. Setting the PortIf 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-16

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-17

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);

}}

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-18

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-19

4. Packaging the WAR file (i) Use Deploytool to create a standalone WAR module

Dickson Chiu 2005 CSIT600c p1-20

4. Packaging the WAR file (ii) Use Deploytool to create a standalone WAR module

Dickson Chiu 2005 CSIT600c p1-21

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-22

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 differentnaming

Dickson Chiu 2005 CSIT600c p1-23

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-24

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-25

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-26

Static Stub - Client Codepackage staticstub;import javax.xml.rpc.Stub;public class HelloClient { private String endpointAddress; 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!”

Generated by wscompile before writing this

program (i.e., static and implementation-specific)

Dickson Chiu 2005 CSIT600c p1-27

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/jax-rpc/ri/config">    <wsdl location="http://localhost:8080/hello-jaxrpc/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-28

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-29

Example 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 = args[0] + "?WSDL"; String nameSpaceUri = "urn:Foo"; String serviceName = "MyHelloService"; String portName = "HelloIFPort";

System.out.println("UrlString = " + UrlString);

URL helloWsdlUrl = new URL(UrlString);

ServiceFactory serviceFactory = ServiceFactory.newInstance();

Service helloService = serviceFactory.createService(helloWsdlUrl, new QName(nameSpaceUri, serviceName));

dynamicproxy.HelloIF myProxy = (dynamicproxy.HelloIF) helloService.getPort

(new QName(nameSpaceUri,portName), dynamicproxy.HelloIF.class);

System.out.println(myProxy.sayHello(“Buzz”));

} catch (Exception ex) { ex.printStackTrace(); } }}

Dickson Chiu 2005 CSIT600c p1-30

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-31

DII Client Examplepackage 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]);

try {

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();

} } }

Dickson Chiu 2005 CSIT600c p1-32

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-33

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-34

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-35

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-36

JAXM clientNot 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

Dickson Chiu 2005 CSIT600c p1-37

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-38

Using SAAJ API to call a Web Service

Steps1. Create SOAP message2. Populate SOAP message3. Add attachments (optional)4. Initialize SOAP connection5. Send SOAP message6. 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/saaj-impl.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-39

SAAJ Example Codeimport 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-40

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(); response.writeTo(System.out);

} catch (Exception ex) { ex.printStackTrace(); } }}

<SOAP-ENV:Envelope xmlns:SOAP-ENV="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-41

SAAJ Result Message

<soap:Envelopesoap: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-42

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-43

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