5.2 jax-rpc. caso de estudio: apache axis -...

62
5.2 JAX-RPC. Caso de estudio: Apache Axis

Upload: buinhi

Post on 20-Sep-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

5.2 JAX-RPC. Caso de estudio: Apache Axis

Introducción (1)

n WSDLn Lenguaje (aplicación XML) para especificar interfaces

remotosn El compilador de WSDL permite generar los stubs y

skeletons para poder invocar e implementar servicios web

n JAX-RPCn API de programación estándar en Java para implementar e

invocar operaciones de Servicios Web mediante el paradigma de los RPCs

n La especificación todavía no está terminadan Estas transparencias se basan en la versión 0.7 de la

especificación

n Trabajaremos con Apache Axisn Implementación OpenSource y gratuita de JAX-RPCn Estas transparencias se basan en la versión Beta 1 de Axis

Introducción (2)

n WSDL es un lenguaje complejon Afortunadamente, casi todas las APIs basadas en

RPCs (ej.: JAX-RPC) permiten n Definir una interfaz remota en el propio lenguaje de

implementaciónn Usar un compilador para generar el documento WSDL a

partir del interfaz remoton El documento WSDL generado es útil para que un cliente

(quizás escrito en un lenguaje distinto al del servidor) pueda usar su compilador de WSDL para obtener el stub del interfaz remoto

Introducción (3)

Interfaz Java

Compilador Java2WSDL

Documento WSDL

Compilador WSDL2Java

Stubs, skeletons y tipos Java

Compilador Java

n Con JAXP-RPC ...

Introducción (4)

n Modelos de implementación de servicios webn Modelo basado en servlets (aplicación web J2EE)n Modelo basado en EJBn Modelo basado en J2SE

n Modelos de implementación de clientesn Modelo basado en J2EE (aplicación web J2EE o EJB)n Modelo basado en J2SE

n Estudiaremos la siguiente combinación

Servidor web J2EE

Aplicaciones web

Internet

Cliente J2SE

HTTP HTTPwar

Introducción (5)

n Servidor (contenedor) de aplicaciones web J2EEn J2EE incluye un API para implementar aplicaciones web en

Javan API de servlets y JSP

n Una aplicación web puede incluir uno o varios servicios web (o puede contener sólo servicios web)

n Cada aplicación web se empaqueta en un fichero warn Un servidor de aplicaciones web puede tener varias

aplicaciones web instaladasn Implementar un servicio web sólo consiste en hacer una

clase que implementa el interfaz remoto, y empaquetar ésta y las clases generadas por el compilador de WSDL a Java que requiere la implementación del servicio en el fichero war

n Axis sólo implementa este modelo de programación de servicios web

Introducción (y 6)

n ¿ Qué es Axis ?n Un conjunto de librerías (ficheros jar) que se han de

instalar en el servidor de aplicaciones webn Incluye

n Herramientas (ej.: compiladores Java2WSDL y WSDL2Java)n Un servlet que

n Recibe las peticiones SOAP sobre HTTP que envían los clientesn Invoca la operación correspondiente sobre el servicio webn Devuelve una respuesta SOAP sobre HTTP con el resultado de la

operación

n Se puede instalar en cualquier servidor de aplicaciones web J2EEn En particular, usaremos Apache Tomcat

Ejemplo StockQuote

n Usaremos el ejemplo StockQuote para ilustrar JAX-RPCn Paquetes es.udc.fbellas.corbaws.stockquote.{wsdl,

client}

n Servicio Web que ofrece una interfaz con una operación que a partir de un conjunto de identificadores de valores bursátiles devuelve sus cotizaciones

n Cada cotización incluyen Su identificadorn Su valorn El número de segundos de antigüedad que tiene el valor (el valor

real actual sería ligeramente distinto)

StockQuoteProvider

Clientestandalone

Servidor de aplicaciones web

InternetHTTP HTTP

es.udc.fbellas.corbaws.stockquote.wsdl.StockQuoteProvider

package es.udc.fbellas.corbaws.stockquote.wsdl;

import java.rmi.Remote;import java.rmi.RemoteException;

public interface StockQuoteProvider extends Remote {

TradePrice[] getLastTradePrices(String[] tickerSymbols) throwsRemoteException, IncorrectTickerSymbolException;

}

es.udc.fbellas.corbaws.stockquote.wsdl.TradePrice (1)

package es.udc.fbellas.corbaws.stockquote.wsdl;

import java.io.Serializable;

public class TradePrice implements Serializable {private String tickerSymbol;private double price;private int elapsedSeconds;

public String getTickerSymbol() {return tickerSymbol;

}

public void setTickerSymbol(String tickerSymbol) {this.tickerSymbol = tickerSymbol;

}

public double getPrice() {return price;

}

es.udc.fbellas.corbaws.stockquote.wsdl.TradePrice (y 2)

public void setPrice(double price) {this.price = price;

}

public int getElapsedSeconds() {return elapsedSeconds;

}

public void setElapsedSeconds(int elapsedSeconds) {this.elapsedSeconds = elapsedSeconds;

}

}

es.udc.fbellas.corbaws.stockquote.wsdl.IncorrectTickerSymbolException

public class IncorrectTickerSymbolException extends Exception {

private String incorrectTickerSymbol;

public IncorrectTickerSymbolException(String incorrectTickerSymbol) {

this.incorrectTickerSymbol = incorrectTickerSymbol;

}

public String getIncorrectTickerSymbol() {return incorrectTickerSymbol;

}

}

Visión global de WSDL

n Dejaremos momentáneamente la explicación de los detalles de la definición del interfaz remoto StockQuoteProvider y sus tipos asociados

n Una vez compilados los anteriores ficheros Java, se puede obtener el documento WSDL

n Un documento WSDL consta de varias partesn Definición de tipos de datosn Definición de mensajesn Definición de puertosn Definición de bindingsn Definición de servicios

n Vamos a echar un vistazo al fichero generadon Objetivo: comprender el formato general de un documento

WSDL

StockQuoteProvider.wsdl (1)<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions

targetNamespace="http://wsdl.stockquote.corbaws.fbellas.udc.es" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:intf="http://wsdl.stockquote.corbaws.fbellas.udc.es" xmlns:impl="http://wsdl.stockquote.corbaws.fbellas.udc.es-impl" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/">

<types><schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://wsdl.stockquote.corbaws.fbellas.udc.es"><complexType name="ArrayOf_SOAP-ENC_string"><complexContent><restriction base="SOAP-ENC:Array"><attribute ref="SOAP-ENC:arrayType"

wsdl:arrayType="xsd:string[]"/></restriction></complexContent></complexType><element name="ArrayOf_SOAP-ENC_string" nillable="true" type="intf:ArrayOf_SOAP-ENC_string"/>

StockQuoteProvider.wsdl (2)<complexType name="TradePrice">

<sequence><element name="tickerSymbol" nillable="true" type="xsd:string"/><element name="price" type="xsd:double"/><element name="elapsedSeconds" type="xsd:int"/></sequence></complexType><complexType name="ArrayOfTradePrice"><complexContent><restriction base="SOAP-ENC:Array"><attribute ref="SOAP-ENC:arrayType"

wsdl:arrayType="intf:TradePrice[]"/></restriction></complexContent></complexType><element name="ArrayOfTradePrice" nillable="true" type="intf:ArrayOfTradePrice"/>

</schema></types>

Definición de tipos de datos - Comentarios

n Es posible usar varios sistemas de tiposn El uso de un esquema XML es el más habitualn Cuando el protocolo que se usa es SOAP, también se pueden

usar tipos SOAPn En el ejemplo se definen

n El tipo complejo ArrayOf_SOAP-ENC_string, que corresponde al tipo Java String[]n Los tipos complejos que representan vectores, se definen como una

especialización por restricción de SOAP-ENC:Array

n Los tipos complejos TradePrice y ArrayOfTradePrice, que corresponden a los tipos Java TradePrice y TradePrice[]

n Los elementos ArrayOf_SOAP-ENC_string y ArrayOfTradePrice

n El atributo nillable con valor true especifica que el correspondiente elemento puede tomar el valor nil (null en Java)

StockQuoteProvider.wsdl (3)<wsdl:message name="getLastTradePricesResponse">

<wsdl:part name="return" type="intf:ArrayOfTradePrice"/></wsdl:message><wsdl:message name="IncorrectTickerSymbolException">

<wsdl:part name="incorrectTickerSymbol" type="SOAP-ENC:string"/></wsdl:message><wsdl:message name="getLastTradePricesRequest">

<wsdl:part name="in0" type="intf:ArrayOf_SOAP-ENC_string"/></wsdl:message>

<wsdl:portType name="StockQuoteProvider"><wsdl:operation name="getLastTradePrices" parameterOrder="in0">

<wsdl:input message="intf:getLastTradePricesRequest"/><wsdl:output message="intf:getLastTradePricesResponse"/><wsdl:fault name="IncorrectTickerSymbolException"

message="intf:IncorrectTickerSymbolException"/></wsdl:operation>

</wsdl:portType>

Definición de mensajes y puertos – Comentarios (1)

n Definición de mensajesn Especifica los mensajes que se pueden intercambiar clientes

y servidoresn Cada mensaje consta de “partes”, donde cada parte

especifica un parámetro del mensaje, un valor de retorno o una excepción

n Definición de puertosn Un puerto especifica un conjunto de operacionesn Cada operación indica el mensaje de entrada (petición del

cliente al servicio), el de salida (respuesta del servicio si noocurre ninguna excepción) y los posibles mensajes fault(excepciones) que puede devolver la operación

Definición de mensajes y puertos – Comentarios (y 2)

n Definición de puertos (cont)n Tipos de parámetros (idem CORBA)

n In: parte que sólo aparece en un mensaje de entradan Out: parte que sólo aparece en un mensaje de salidan Inout: parte que aparece en un mensaje de entrada y salida

n Valor de retornon Parte con name="return"

StockQuoteProvider.wsdl (4)<wsdl:binding name="StockQuoteProviderSoapBinding"

type="intf:StockQuoteProvider"><wsdlsoap:binding style="rpc"

transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="getLastTradePrices">

<wsdlsoap:operation soapAction=""/><wsdl:input>

<wsdlsoap:body use="encoded"encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://wsdl.stockquote.corbaws.fbellas.udc.es"/>

</wsdl:input><wsdl:output>

<wsdlsoap:body use="encoded"encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"namespace="http://wsdl.stockquote.corbaws.fbellas.udc.es"/>

</wsdl:output></wsdl:operation>

</wsdl:binding>

StockQuoteProvider.wsdl (y 5)<wsdl:service name="StockQuoteProviderService">

<wsdl:port name="StockQuoteProvider“binding="intf:StockQuoteProviderSoapBinding">

<wsdlsoap:address location="http://localhost:8080/StockQuote/services/StockQuoteProvider"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

Definición de bindings y servicios – Comentarios

n Definición de bindingsn Un binding especifica detalles particulares al protocolo usado

(en este caso, SOAP) para enviar los mensajes

n Definición de serviciosn Un servicio especifica un conjunto de puertos, especificando

para cada uno de ellos la dirección de contacto que tiene que usar un cliente

Mappings

n JAX-RPC especifican El mapping de Java a WSDLn El mapping de WSDL a Java

n Dado que normalmente no se escriben documentos WSDL, no es preciso conocer ambos mappings en detalle, pero sí lo esencialn Mapping de Java a WSDL

n Estudiaremos cuáles son los tipos Java que podemos emplear en la definición de interfaces remotos y cómo se deben definir los interfaces

n Mapping de WSDL a Javan Estudiaremos cuáles son los tipos Java que se generan cuando

partimos de un documento WSDL

Mapping de Java a WSDL (1)

n Tipos válidos JAXP-RPC: tipos que se pueden emplear en la definición de interfaces remotosn Tipos primitivos y sus contrapartidas objetualesn Clases estándarn Tipos valor JAX-RPCn Arrays de tipos válidos

Mapping de Java a WSDL (2)

n Tipos primitivos y sus contrapartidas objetuales

xsd:doubledouble

xsd:floatfloat

xsd:longlong

xsd:intint

xsd:shortshort

xsd:bytebyte

xsd:booleanbooleanTipo WSDLTipo Java

n En el caso de las contrapartidas objetuales, el correspondiente elemento lleva el atributo nillable a true

Mapping de Java a WSDL (3)

n Clases estándar

xsd:dateTimejava.util.Date

xsd:dateTimejava.util.Calendar

xsd:decimaljava.math.BigDecimal

xsd:integerjava.math.BigInteger

xsd:stringjava.lang.String

Tipo WSDLTipo Java

n NOTA: Axis no soporta java.util.Calendar

n Arrays de tipos válidosn Se mapean a tipos complejos derivados por restricción de un

array SOAP, a excepción de byte[] (xsd:base64Binary)

Mapping de Java a WSDL (4)

n Tipos valor JAX-RPCn En general estas clases deben tener

n Constructor sin argumentos públicon Atributos públicos de tipos válidos o usar las convenciones de

nombrado de JavaBeans para sus atributos (métodos getXXXy setXXX)

n Pueden heredar de otras clases valorn Se mapean a tipos WSDL complejos con compositor all

(structs XML)n En caso de herencia, el tipo complejo se define por derivaciónn NOTA: Axis genera usa el compositor sequence

n Es buena práctica que implementen java.io.Serializable (interfaz marker)

n Ej.: TradePrice

Mapping de Java a WSDL (5)

n Definición de interfacesn Extienden java.rmi.Remote (interfaz marker)n Todas las operaciones deben declarar java.rmi.RemoteException

n Cada interfaz se mapea a un puerton Dado que en WSDL no existe herencia entre puertos, si un

interfaz deriva de otro, el puerto hijo incluye todas las operaciones del padre

n Una operación no puede recibir como parámetro (o devolver como valor de retorno) una referencia a un interfaz remoton Actualmente SOAP no ofrece soporte para ello

n Ej.: StockQuoteProvider

Mapping de Java a WSDL (6)

n Excepcionesn Extienden java.lang.Exceptionn Definen un constructor público que recibe un parámetron Definen un método getXXX para recuperar el valorn Ej.: IncorrectTickerSymbolExceptionn NOTA

n En Axis las excepciones definidas por el usuario en los interfaces remotos no funcionan correctamente

n Ejemplo StockQuote: si el cliente recibe una excepción IncorrectTickerSymbolException, el método getTickerSymbol devuelve null

Mapping de Java a WSDL (y 7)

n Otros tiposn Si se desean usar otros tipos para los que JAXP-RPC no tiene

soporte directo (ej.: java.util.Collection), JAX-RPC permite implementar clases serializadoras y deserializadoras

n Serializadorn Convierte el valor de un tipo Java a XML

n Deserializadorn Convierte el valor de un tipo XML a Java

n Se espera que los fabricantes de JAX-RPC proporcionen serializadores/deserializadores para clases estándar usualesn Ej.: Axis permite usar el tipo java.util.List

Mapping de WSDL a Java (1)

n Las reglas del mapping de Java a WSDL a la inversan Los structs XML (con compositor all o sequence) se

mapean a una clase Java con métodos getXXX/setXXXpara cada campo del struct

n Además, necesitamos sabern ¿ Cómo se traducen las enumeraciones ?n ¿ Cómo se traducen los parámetros out e inout ?n Si partimos de los interfaces remotos Java, estas dos preguntas

no son relevantes (porque Java no soporta directamente estos dos conceptos), pero sí lo son si partimos de los interfaces WSDL

n También necesitamos conocer algunas clases generadas que son específicas al cliente o al servidorn Las estudiamos como parte del modelo de implementación de

clientes y servidores

Mapping de WSDL a Java (2)

n Enumeracionesn Muy parecido a CORBA

// WSDL<simpleType name=”EyeColor”>

<restriction base=”xsd:string”><enumeration value=”green”/><enumeration value=”blue”/>

</restriction></simpleType>

Mapping de WSDL a Java (3)

n Enumeraciones (cont)

// Javapublic class EyeColor {

public static final String _green = “green”;public static final String _blue = “blue”;public static final EyeColor green = new EyeColor(_green);public static final EyeColor blue = new EyeColor(_blue);

protected EyeColor(String value) { ... }public String getValue() { ... }public static EyeColor fromValue(String value) { ... }public boolean equals(Object obj) { ... }public int hashCode() { ... }

// Otros métodos ...

}

Mapping de WSDL a Java (y 4)

n Parámetros out e inoutn Uso de clases Holder similares a las de CORBAn Existen clases Holder para los tipos WSDL predefinidos en el

paquete javax.xml.rpc.holdersn Ej.: FloatHolder

n Para los tipos definidos por el programador, el compilador de WSDL genera clases Holder con el formato

final public class <Foo>Holderimplements javax.xml.rpc.holders.Holder {

public <Foo> value;

public <Foo>Holder() { ... }public <Foo>Holder(<Foo> value) { ... }

}

Implementación de servicios web en un servidor de aplicaciones web J2EE (1)

Servidor aplicaciones web J2EE

Aplicaciones web

Internet

Cliente

HTTP HTTPwar

n Implementar un servicio web sólo consiste en hacer una clase que implementa el interfaz remoto, y empaquetar ésta y las clases generadas por el compilador de WSDL a Java que requiere la implementación del servicio en el fichero war

n Axis sólo implementa este modelo de programación de servicios web

Implementación de servicios web en un servidor de aplicaciones web J2EE (2)

n Usaremos Tomcat como servidor de aplicaciones webn Es un servidor de aplicaciones web conforme con el estándar

J2EEn No tiene soporte para servicios webn Axis consiste en un conjunto de librerías (ficheros jar) que

han de estar disponibles a la aplicación webn Se pueden incluir en el fichero war de la aplicación web

n Se pueden instalar en Tomcat para que estén disponibles para cualquier aplicación web

Implementación de servicios web en un servidor de aplicaciones web J2EE (y 3)

n Requisitos de la clase de implementaciónn Implementa el interfaz remoton Ofrece un constructor público sin argumentosn Tiene que ser thread-safen NOTA

n En Axis, el nombre de la clase de implementación es XXXSoapBindingImpl, siendo XXX el nombre del interfaz remoto

n Ej.: StockQuoteProviderSoapBindingImpl

es.udc.fbellas.corbaws.stockquote.wsdl.StockQuoteProviderSoapBindingImpl (1)

package es.udc.fbellas.corbaws.stockquote.wsdl;import java.util.Map;import java.util.HashMap;import java.util.List;import java.util.ArrayList;

public class StockQuoteProviderSoapBindingImpl implementsStockQuoteProvider {

private Map tradePrices;

public StockQuoteProviderSoapBindingImpl() {

TradePrice ibmTradePrice = new TradePrice();ibmTradePrice.setTickerSymbol("IBM");ibmTradePrice.setPrice(10.5);ibmTradePrice.setElapsedSeconds(60*20);// ...

tradePrices = new HashMap();tradePrices.put(ibmTradePrice.getTickerSymbol(),

ibmTradePrice);// ...

}

es.udc.fbellas.corbaws.stockquote.wsdl.StockQuoteProviderSoapBindingImpl (y 2)

public TradePrice[] getLastTradePrices(String[] tickerSymbols)throws IncorrectTickerSymbolException {

List requestedTradePrices = new ArrayList();

for (int i=0; i<tickerSymbols.length; i++) {

TradePrice tradePrice = (TradePrice) tradePrices.get(tickerSymbols[i]);

if (tradePrice == null) {throw new IncorrectTickerSymbolException(

tickerSymbols[i]);}

requestedTradePrices.add(tradePrice);

}

return (TradePrice[]) requestedTradePrices.toArray(new TradePrice[0]);

}}

Empaquetamiento de aplicaciones web (1)

n En J2EE, las aplicaciones web se empaquetan en ficheros warn En particular, una aplicación web puede incluir servicios web

n jar cvf aplicacionWeb.war directorion Opciones similares al comando Unix tar

n Ant incluye la tarea interna warn Estructura de un fichero war

n Directorio WEB-INF/classesn Ficheros .class que conforman la aplicación web, agrupados

en directorios según su estructura en paquetesn ¡ Sin ficheros fuente !

n Directorio WEB-INF/libn Ficheros jar de librerías que usa la aplicaciónn ¡ Sin ficheros fuente !

Empaquetamiento de aplicaciones web (y 2)

n Estructura de un fichero war (cont)n WEB-INF/web.xml

n Configuración estándar de la aplicación web

n Directorio raíz y subdirectoriosn Vista de la aplicación (ej.: ficheros HTML, páginas JSP,

imágenes, etc.)n Visible a los navegadores

n Lo que hay debajo de WEB-INF sólo es visible a los servlets y páginas JSP de la aplicación

n Un fichero war se puede instalar (deployment) en cualquier servidor de aplicaciones web conforme a J2EE

jar tvf Movies.war (1)WEB-INF/lib/crimson.jarWEB-INF/lib/jaxp.jarWEB-INF/lib/axis.jarWEB-INF/lib/clutil.jarWEB-INF/lib/commons-logging.jarWEB-INF/lib/jaxrpc.jarWEB-INF/lib/log4j-core.jarWEB-INF/lib/tt-bytecode.jarWEB-INF/lib/wsdl4j.jarWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

StockQuoteProvider.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

IncorrectTickerSymbolException.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

TradePrice.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

StockQuoteProviderService.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

StockQuoteProviderServiceLocator.class

jar tvf Movies.war (y 2)WEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

StockQuoteProviderSoapBindingStub.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl/

StockQuoteProviderSoapBindingSkeleton.classWEB-INF/classes/es/udc/fbellas/corbaws/stockquote/wsdl

/StockQuoteProviderSoapBindingImpl.classWEB-INF/web.xml

Comentarios

n WEB-INF/libn jaxp.jar

n API de JAXPn crimson.jar

n Implementación OpenSource de JAXPn Axis requiere JAXP

n jaxrpc.jar, axis.jar, clutil.jar, commons-logging.jar, log4j-core.jar, tt-bytecode.jar, wsdl4j.jarn Axis: API de JAX-RPC, implementación y herramientas

n WEB-INF/classesn Contiene las clases del paquete es.udc.fbellas.corbaws.stockquote.wsdl

n Definición del servicio web e implementaciónn En el ejemplo, por sencillez, se han incluido algunas que no son

necesarias para la implementación del servicio (ej.: el stub)

web.xml (1)<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN""http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>

<display-name>Apache-Axis</display-name>

<servlet><servlet-name>AxisServlet</servlet-name><display-name>Apache-Axis Servlet</display-name><servlet-class>

org.apache.axis.transport.http.AxisServlet</servlet-class>

</servlet>

web.xml (y 2)<servlet><servlet-name>AdminServlet</servlet-name><display-name>Axis Admin Servlet</display-name><servlet-class>

org.apache.axis.transport.http.AdminServlet</servlet-class><load-on-startup>100</load-on-startup>

</servlet>

<servlet-mapping><servlet-name>AxisServlet</servlet-name><url-pattern>servlet/AxisServlet</url-pattern>

</servlet-mapping>

<servlet-mapping><servlet-name>AxisServlet</servlet-name><url-pattern>/services/*</url-pattern>

</servlet-mapping>

<servlet-mapping><servlet-name>AdminServlet</servlet-name><url-pattern>servlet/AdminServlet</url-pattern>

</servlet-mapping>

</web-app>

Comentarios (1)

n Se declaran los servlets AxisServlet y AdminServletn Sus clases están en axis.jar

n AxisServletn El servidor de aplicaciones web le pasará todas las

peticiones dirigidas a las URLs http://.../NombreAplicacionWeb/services/*

<servlet-mapping><servlet-name>AxisServlet</servlet-name><url-pattern>/services/*</url-pattern>

</servlet-mapping>

n En este caso, asumiendo que instalemos la aplicación web con el nombre StockQuote, el cliente usará la URL http://.../StockQuote/services/StockQuoteProvider para acceder al puerto StockQuoteProvider (es la URL que aparece en el documento WSDL)

Comentarios (y 2)

n AxisServlet (cont)n El servlet invocará la operación correspondiente sobre el

servicio web al que va dirigida la petición, y finalmente enviará una respuesta SOAP con el resultado de la operación

n AdminServletn Permite realizar tareas de administración sobre los servicios

web instalados (ej.: activarlos, desactivarlos, etc.)n Axis proporciona una aplicación standalone para

comunicarse con este servlet

es.udc.fbellas.corbaws.stockquote.client.Client (1)

package es.udc.fbellas.corbaws.stockquote.client;

import java.util.Calendar;import java.util.Date;import java.rmi.RemoteException;import java.net.URL;

import es.udc.fbellas.corbaws.stockquote.wsdl.TradePrice;import es.udc.fbellas.corbaws.stockquote.wsdl.StockQuoteProvider;import es.udc.fbellas.corbaws.stockquote.wsdl.

StockQuoteProviderService;import es.udc.fbellas.corbaws.stockquote.wsdl.

StockQuoteProviderServiceLocator;import es.udc.fbellas.corbaws.stockquote.wsdl.

IncorrectTickerSymbolException;

class Client {

public static void main (String args[]) {

es.udc.fbellas.corbaws.stockquote.client.Client (2)

try {

/* Check arguments. */if (args.length < 1) {

System.err.println("Usage: " + Client.class.getName() +" stockQuoteProviderURL" +" [tickerSymbol1 tickerSymbol2 ...]");

System.exit(-1);}

/* Get argument values. */ URL stockQuoteProviderURL = new URL(args[0]);String[] tickerSymbols = new String[args.length-1];for (int i=0; i<tickerSymbols.length; i++) {

tickerSymbols[i] = args[i+1];}

/* Construct an instance of the port proxy. */StockQuoteProviderService stockQuoteProviderService =

new StockQuoteProviderServiceLocator();StockQuoteProvider stockQuoteProvider =

stockQuoteProviderService.getStockQuoteProvider(stockQuoteProviderURL);

es.udc.fbellas.corbaws.stockquote.client.Client (y 3)

/* Gest last trade prices. */TradePrice[] tradePrices =

stockQuoteProvider.getLastTradePrices(tickerSymbols);

/* Print last trade prices. */for (int i=0; i<tradePrices.length; i++) {

System.out.println("Ticker symbol = " +tradePrices[i].getTickerSymbol() + " | " +"Price = " + tradePrices[i].getPrice() + " | " +"Elapsed seconds = " + tradePrices[i].getElapsedSeconds());

}

} catch (IncorrectTickerSymbolException e) {System.err.println("Incorrect ticker symbol: " +

e.getIncorrectTickerSymbol());} catch (Exception e) {

e.printStackTrace();}

}

}

Clientes de servicios web (1)

n Tipos de clientesn Clientes standalone J2SEn Clientes J2EE (aplicaciones web o EJBs)

n StockQuoteProviderServicen Interfaz generado por el compilador de WSDL a Javan Su nombre coincide con el nombre del servicio declarado en

el fichero WSDLn Proporciona métodos get<PortType>

n Devuelven una instancia del stub/proxy del puerton De momento, en JAX-RPC sólo está estandarizado un método get sin parámetros por cada puerton En un cliente J2SE, asume que la URL del puerto es la declarada

en el documento WSDLn En un cliente J2EE, se puede configurar el entorno para que use

una URL específican El ejemplo usa un método get<PortType> (específico de

Axis) que recibe la URL del puerto como parámetro

Clientes de servicios web (y 2)

n StockQuoteProviderServiceLocatorn Clase concreta generada por el compilador de WSDL a Javan Es específica de Axisn Implementa el interfaz StockQuoteProviderServicen En un cliente J2EE, se puede obtener una referencia al

interfaz StockQuoteProviderService sin conocer la clase que lo implementan Se usa JNDI (Java Naming and Directory Interface)

n StockQuoteProvidern Interfaz del puerton Escrito por el programador o generado por el compilador de

WSDL a Java

n InvocaciónStockQuoteClient.shhttp://.../StockQuote/services/StockQuoteProvider IBM SUN MIC

TCPMonitor (1)

n Axis incluye una herramienta que permite monitorizar las peticiones y respuestas SOAP que envían clientes y servidoresn Actúa como un “túnel”n Recibe las peticiones del cliente, las muestra en pantalla y

las redirige al servicion Recibe las respuesta del servicio, las muestra en pantalla y

se las envía al cliente

TCPMonitor (2)

TCPMonitor.sh 8000 localhost 8080(escucha por el puerto 8000 y redirige a localhost:8080)

$TOMCAT_HOME/bin/startup.sh(por defecto escucha por el puerto 8080)

StockQuoteClient.sh http://localhost:8000/StockQuote/services/StockQuoteProvider IBM SUN MIC

1: Petición SOAP

2: Petición SOAP

3: Respuesta SOAP

4: Respuesta SOAP

TCPMonitor (y 3)

getLastTradePrices: petición SOAP (1)

POST /StockQuote/services/StockQuoteProvider HTTP/1.0Content-Length: 720Host: localhostContent-Type: text/xml; charset=utf-8SOAPAction: ""

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

getLastTradePrices: petición SOAP (y 2)

<SOAP-ENV:Body>

<ns1:getLastTradePrices xmlns:ns1="http://wsdl.stockquote.corbaws.fbellas.udc.es">

<in0 xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:string[3]">

<item xsi:type="xsd:string">IBM</item>

<item xsi:type="xsd:string">SUN</item>

<item xsi:type="xsd:string">MIC</item>

</in0>

</ns1:getLastTradePrices>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

getLastTradePrices: respuesta SOAP (1)

HTTP/1.1 200 OKContent-Type: text/xml; charset=utf-8Content-Length: 1802Date: Sun, 14 Apr 2002 15:57:38 GMTServer: Apache Tomcat/4.0.1 (HTTP/1.1 Connector)

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

getLastTradePrices: respuesta SOAP (2)

<SOAP-ENV:Body>

<ns1:getLastTradePricesResponse SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://wsdl.stockquote.corbaws.fbellas.udc.es">

<getLastTradePricesResult xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="ns1:TradePrice[3]" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<item href="#id0"/>

<item href="#id1"/>

<item href="#id2"/>

</getLastTradePricesResult>

</ns1:getLastTradePricesResponse>

getLastTradePrices: respuesta SOAP (y 3)

<multiRef id="id2" SOAP-ENC:root="0" xsi:type="ns2:TradePrice“xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/“xmlns:ns2="http://wsdl.stockquote.corbaws.fbellas.udc.es">

<elapsedSeconds xsi:type="xsd:int">300</elapsedSeconds>

<price xsi:type="xsd:double">20.3</price>

<tickerSymbol xsi:type="xsd:string">MIC</tickerSymbol>

</multiRef>

...

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Comentarios

n El stub del cliente envía una petición SOAP para invocar la operación getLastTradePrices sobre el puerto StockQuoteProvidern El parámetro de la operación (String[]) se ha serializado

a XMLn AxisServlet recibe la petición SOAP

n Determina que el cliente desea invocar la operación getLastTradePrices sobre StockQuoteProvider

n Deserializa el parámetro de la operaciónn Invoca la operaciónn Serializa el valor de retorno (TradePrice[]) de la

operaciónn Envía una respuesta SOAP

n El stub recibe la respuesta SOAPn Deserializa el valor de retorno