Download Seccion 5 - Servicios Web

Document related concepts
no text concepts found
Transcript
MII 733 Computación Móvil
José Miguel Rubio L.
Oficina 3-20
http://www.inf.ucv.cl/~jrubio
[email protected]
Sección 5
Servicios Web con
Axis
José Miguel Rubio L.
Oficina 3-20
http://www.inf.ucv.cl/~jrubio
[email protected]
Introducción I
Los Servicios Web son la piedra angular de
cualquier desarrollo de sistemas distribuidos
actual
Los ordenadores hablan unos a otros a través
de la web usando HTTP y otros protocolos.
Un servicio web no tiene interfaz gráfica
Provee una API de métodos que pueden ser
invocados en la web
Diseñados para proveer “servicios”
Introducción II
Futuro en el que los negocios exponen aplicaciones
a clientes como Servicios Web en los cuales se paga
por su uso
Los sistemas de diferentes empresas cooperan unos
con otros a través de la Web
Mientras que DCOM está basado en estándares
propietarios, los Servicios Web lo están en XML y
HTTP
Son independientes de la plataforma y del lenguaje como
CORBA, pero más aceptados
En .NET, IIS y la infraestructura ASP.NET compilan
las fuentes, construyen contratos WSDL y manejan
las peticiones y respuestas de los servicios web.
En Java AXIS realiza una tarea muy similar
SOA
Los servicios web han dado lugar a un nuevo
modo de diseñar sistemas distribuídos:
SOA = colección de servicios
Arquitecturas SOA (Service Oriented Arquitecture)
Más información en http://www.servicearchitecture.com/
http://msdn.microsoft.com/Longhorn/understandin
g/pillars/Indigo/default.aspx?pull=/library/enus/dnbda/html/srorientwp.asp
Servicios Web
Son un estándar basado en protocolos abiertos como
HTTP y SOAP
SOAP es un vocabulario XML que representa RPCs
http://www.w3.org/TR/SOAP
No necesitas ni Windows ni .NET, ni UNIX ni Java para
escribir servicios web
Servicio web = aplicación que:
se ejecuta en un servidor web
expone métodos a clientes
escucha peticiones HTTP representando comandos que invocan
a métodos Web
ejecuta métodos web y devuelve resultados
SOAP
SOAP es un protocolo de comunicación basado en XML útil para la
comunicación entre aplicaciones
Actualmente en versión 1.2, aunque la más utilizada es la 1.1
SOAP es reconocido como el backbone de una nueva generación de
aplicaciones multi-platforma y multi-lenguaje, denominado Servicios Web.
SOAP es un mecanismo para el intercambio de mensajes a través de
Internet independiente de los lenguajes de programación
http://www.w3.org/2000/xp/Group/
Es un protocolo de transporte
Los clientes envían una petición SOAP mediante un HTTP POST
normalmente y reciben un código de respuesta (éxito o error) y una
respuesta SOAP
Un mensaje SOAP es un mensaje XML que consta de un conjunto de
cabeceras opcionales y de un cuerpo.
Petición SOAP
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/so
ap/envelope/">
<soap:Body>
<getProductDetails
xmlns="http://warehouse.example.com/ws">
<productId>827635</productId>
</getProductDetails>
</soap:Body>
</soap:Envelope>
Respuesta SOAP
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getProductDetailsResponse
xmlns="http://warehouse.example.com/ws">
<getProductDetailsResult>
<productName>Toptimate 3-Piece Set</productName>
<productId>827635</productId>
<description>3-Piece luggage set. Black
Polyester.</description>
<price>96.50</price>
<inStock>true</inStock>
</getProductDetailsResult>
</getProductDetailsResponse>
</soap:Body>
</soap:Envelope>
Apache AXIS
AXIS es un motor SOAP, una framework para construir tanto la
parte servidora como cliente de Servicios Web.
Además:
Incluye un servidor
Un servlet que se integra con motores de servlets como Tomcat
Soporte extensivo del estándar Web Service Description Language
(WSDL)
Una herramienta para generar clases Java a partir de WSDL
Un conjunto de aplicaciones de ejemplo
Una herramienta para la monitorización de los paquetes TCP/IP
Open source, disponible en:
http://ws.apache.org/axis/
WS-*
Apache Axis
Axis es disponible en el fichero axis.jar;
que implementa la API JAX-RPC API
declarada en los ficheros JAR jaxrpc.jar
y saaj.jar. Requiere varias bibliotecas
de ayuda, para logeo, procesamiento
WSDL e introspección.
Características AXIS
La arquitectura de AXIS está basada en cadenas
configurables de manejadores de mensajes que
implementan pequeños fragmentos de funcionalidad de
una manera flexible
Sus propiedades principales:
Rápido implementado con un procesador XML SAX
Flexible
Estable
Orientado a Compontes
Soporta WSDL 1.1
Apache EXtensible Interaction System (AXIS) motor
SOAP muy configurable
Proceso de Generación de
Programas con Axis
Instalación Axis
1.
Bajarse la distribución de Apache Axis de
http://ws.apache.org/axis/
La versión actual es 1.2RC2
2.
3.
4.
Bajarse tanto versión binaria (ya compilado) como fuente (contiene
ejemplos)
Instalar un contenedor de servlets como Tomcat 5
Copiar el directorio axis-1_2RC2\webapps\axis contenido
en la distribución de Axis en %TOMCAT_HOME\webapps
Instalar .jar terceros necesitados por Axis, copiándolos en
%TOMCAT_HOME%\common\lib:
Junit.jar (Junit Testing System http://www.junit.org/index.htm)
mail.jar (Java Mail http://java.sun.com/products/javamail/)
activation.jar (Java Beans Activation Framework http://java.sun.com/products/javabeans/glasgow/jaf.html)
Instalación Axis
5.
6.
7.
Arrancar el servidor web
Validar la instalación:
http://127.0.0.1:8080/axis/
(hacer clic en Validate)
Validar un SOAP endpoint:
http://localhost:8080/axis/s
ervices/Version?method=getVe
rsion
Axis soporta HTTP GET
Creando Servicios Web .jws
Axis tiene un método muy sencillo de
crear servicios web básicos, mediante el
mecanismo de ficheros .jws
Cuando
alguien solicita a través de una url un
fichero .jws, éste es compilado y ejecutado
Revisar ejemplo:
http://localhost:8080/axis/Echo
Headers.jws?method=list
Cómo Instalar un Nuevo
Servicio Web
Dos pasos:
1.
Copiar el código del servicio web bajo el directorio
%TOMCAT_HOME%\webapps\axis WAR
2.
En el directorio WEB-INF\classes de AXIS copiar las
clases de tu nuevo servicio web
Si tus clases están en un .jar simplemente copiarlas a
WEB-INF\lib
Informar al motor de AXIS acerca del nuevo fichero
Se realiza haciendo un POST de un fichero de explotación
(wsdd) mediante el programa AdminClient
El Web Service Deployment Descriptor describe en XML cuál
es el servicio web y qué métodos exporta
Compilando Servicios Web
Para compilar servicios web necesitamos colocar en nuestro
CLASSPATH las dependencias de AXIS
set AXIS_HOME=c:\axis
set AXIS_LIB=%AXIS_HOME%\lib
set
AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons
-discovery.jar;%AXIS_LIB%\commonslogging.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.ja
r;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xmlapis.jar;%AXIS_LIB%\xercesImpl.jar
Luego podemos hacer:
javac –classpath %AXISCLASSPATH%
java -cp %AXISCLASSPATH% ...
Ejecución del AdminClient
Buscar en axis\samples\stock un ejemplo de un
fichero de explotación web de AXIS: deploy.wsdd.
Registrar el servicio web mediante el comando:
java -cp %AXISCLASSPATH%
org.apache.axis.client.AdminClient lhttp://localhost:8080/axis/services/AdminServi
ce deploy.wsdd
Para probar el servicio web acceder a:
java -cp .;%AXISCLASSPATH% samples.stock.GetQuote
lhttp://localhost:8080/axis/servlet/AxisServlet
-uuser1 -wpass1 XXX
Cómo Añadir AXIS a tu
Aplicación Web
Los pasos a seguir son:
1.
2.
3.
4.
Añadir axis.jar, wsdl.jar, saaj.jar,
jaxrpc.jar y otras bibliotecas dependientes a tu
fichero WAR
Copiar todas las declaraciones del servlet de Axis y
sus mapeos de axis/WEB-INF/web.xml y
añadirlos a tu propio web.xml
Construir y desplegar la aplicación web
Ejecutar el AdminClient de AXIS contra tu propia
aplicación web, en vez de contra AXIS, cambiando
la url con la que invocas a AXIS
Consumiendo un Servicio Web
Vamos a desarrollar una pequeña aplicación cliente que
consume el servicio web más sencillo que podemos
imaginar, implementado en Echo.jws, que copiaremos
a %TOMCAT_HOME%\webapps\AXIS\:
public class Echo {
public String echoString(String msg)
{
return msg;
}
}
Consumiendo un Servicio Web
A continuación, vamos a definir un cliente
que me permita consumir este servicio
web desde línea de comando
Desde un navegador podríamos invocar a
este servicio mediante la URL:
http://localhost:8080/axis/Echo.jws?method=ec
hoString&msg=hola
Consumiendo un Servicio Web
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class EchoClient
{
public static void main(String [] args) {
try {
String endpoint = "http://localhost:8080/axis/Echo.jws";
Service service = new Service();
Call
call
= (Call) service.createCall();
service.createCall();
call.setTargetEndpointAddress(
call.setTargetEndpointAddress( new java.net.URL(endpoint)
java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/",
QName("http://soapinterop.org/", "echoString
"echoString")
echoString") );
String ret = (String) call.invoke(
call.invoke new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
Consumiendo un Servicio Web
Los objetos Service y Call son los
objetos estándar JAX-RPC que permiten
guardar metadatos sobre el servicio a
invocar.
Consumiendo un Servicio Web
Al invocar el método la siguiente información aparecería en el navegador:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoString xmlns:ns1="http://soapinterop.org/">
<arg0 xsi:type="xsd:string">Hello!</arg0>
</ns1:echoString>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Consumiendo un Servicio Web
Si deseamos dar nombre a los parámetros solamente
deberemos insertar el siguiente código:
// Call to addParameter/setReturnType as
described in user-guide.html
call.addParameter("testParam",
org.apache.axis.Constants.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
Si queremos indicar a AXIS cuál es el tipo de dato
devuelto haríamos:
call.setReturnType(org.apache.axis.Constants.XSD_
STRING);
Publicando un Servicio Web
con AXIS
Vamos a suponer que tenemos una clase
Calculator que queremos sea
accesible como Servicio Web.
Tenemos dos mecanismos:
través de un fichero .JWS
Registrando el nuevo servicio vía AxisAdmin
usando desplegamiento propietario
A
Publicando con JWS
Sólo para Servicios Web muy sencillos
Con esta instrucción se desplegaría:
copy Calculator.java <your-webapproot>/axis/Calculator.jws
Para invocarlo haríamos:
http://localhost:8080/axis/Calculator.jws
O nos crearíamos nuestros clientes propietarios.
Revisar
samples/userguide/example2/Calculator.java
Calculator.java
public class Calculator {
public int add(int i1, int i2)
{
return i1 + i2;
}
public int subtract(int i1, int i2)
{
return i1 - i2;
}
}
CalcClient.java
import
import
import
import
org.apache.axis.client.Call;
org.apache.axis.client.Service;
org.apache.axis.encoding.XMLType;
org.apache.axis.utils.Options;
import javax.xml.rpc.ParameterMode;
public class CalcClient
{
public static void main(String [] args) throws Exception {
Options options = new Options(args);
String endpoint = "http://localhost:" + options.getPort() +
"/axis/Calculator.jws";
args = options.getRemainingArgs();
if (args == null || args.length != 3) {
System.err.println("Usage: CalcClient <add|subtract> arg1 arg2");
return;
}
String method = args[0];
if (!(method.equals("add") || method.equals("subtract"))) {
System.err.println("Usage: CalcClient <add|subtract> arg1 arg2");
return;
}
CalcClient.java
Integer i1 = new Integer(args[1]);
Integer i2 = new Integer(args[2]);
Service
Call
service = new Service();
call
= (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( method );
call.addParameter( "op1", XMLType.XSD_INT, ParameterMode.IN );
call.addParameter( "op2", XMLType.XSD_INT, ParameterMode.IN );
call.setReturnType( XMLType.XSD_INT );
Integer ret = (Integer) call.invoke( new Object [] { i1, i2 });
System.out.println("Got result : " + ret);
}
}
Custom Deployment
Habrá ocasiones en que queramos exportar
código anteriormente realizado como un servicio
web
Además a menudo se requerirán
configuraciones más sofisticadas: inclusión de
Handlers
Para acceder a toda la flexibilidad configurativa
de AXIS necesitamos utilizar Web Service
Deployment Descriptor (WSDD)
Web Service Deployment
Descriptor
Describe un conjunto de configuraciones que quieres hacer disponible a
AXIS
Por ejemplo:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
>
<service name="MyService" provider="java:RPC">
<parameter name="className"
value="samples.userguide.example3.MyService"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
Indicamos que el servico web MyService de tipo java:RPC es definido
en la clase samples.userguide.example3.MyService y hacemos
disponibles todos los métodos públicos en esa clase
Web Service Deployment
Descriptor
Algunas opciones adicionales que se pueden especificar
en un .wsdd son:
Alcance de los servicios, se pueden definir servicios web con
tres alcances:
request crea un nuevo objeto cada vez que se recibe una
petición al servicio
application un solo objeto servirá todas las peticiones
session un objeto por cada sesión de cliente
Por ejemplo:
<service name="MyService"...>
<parameter name="scope" value=“request"/>
...
</service>
Utilizando el AdminClient
La clase org.apache.axis.client.AdminClient
permite el envío del fichero de explotación al servidor
Tomcat, si está escuchando en un puerto diferente al
8080 hay que enviar el parámetro –p <port>.
java org.apache.axis.client.AdminClient
deploy.wsdd
java org.apache.axis.client.AdminClient list
java org.apache.axis.client.AdminClient
undeploy.wsdd
Revisar samples/userguide/example3.
Manejadores y Cadenas
Los Handlers (o manejadores) permiten pre/post
procesar peticiones a servicios web.
Por ejemplo, para contar el número de invocaciones recibidas
Revisar ejemplo samples/log
En el .wsdd podemos colocar un elemento handler que
puede recibir una serie de parámetros (subelemento
parameter)
Después, podemos definir services que usan los
handler, mediante subelementos requestFlow del
service
Estos handlers son invocados antes de que el provider sea
invocado
Manejadores y Cadenas
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<!-- define the logging handler configuration -->
<handler name="track"
type="java:samples.userguide.example4.LogHandler">
<parameter name="filename" value="MyService.log"/>
</handler>
<!-- define the service, using the log handler we just defined -->
<service name="LogTestService" provider="java:RPC">
<requestFlow>
<handler type="track"/>
</requestFlow>
<parameter name="className"
value="samples.userguide.example4.Service"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
Pasos para Crear un Servicio
Web con Custom Deployment
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Crear un directorio de trabajo:
examples/webservices/ej3customdeployment
Crear la clase Java que define el servicio web (MyService.java)
Crear el cliente web (Client.java)
Crear el descriptor de despliegue para este servicio (deploy.wsdd)
Crear el descriptor para eliminar este servicio (undeploy.wsdd)
cd ej3customdeployment
Compilar el código: javac *.java
Ejecutar el AdminClient: java org.apache.axis.client.AdminClient
deploy.wsdd
copy ej3customdeployment/*.class %TOMCAT_HOME%\axis\WEBINF\classes\ ej3customdeployment
Ejecutar: cd ..; java ej3customdeployment.Client lhttp://localhost:8080/axis/services/MyService "test me!"
MyService.java
package ej3customdeployment;
public class MyService
{
public String serviceMethod(String arg)
{
return arg;
}
}
Client.java
package ej3customdeployment;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
public class Client
{
public static void main(String [] args)
{
try {
Options options = new Options(args);
String endpointURL = options.getURL();
String textToSend;
args = options.getRemainingArgs();
if ((args == null) || (args.length < 1)) {
textToSend = "<nothing>";
} else {
textToSend = args[0];
}
Service service = new Service();
Call
call
= (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpointURL) );
call.setOperationName( new QName("http://ej3_customdeployment", "serviceMethod") );
call.addParameter( "arg1", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType( org.apache.axis.encoding.XMLType.XSD_STRING );
String ret = (String) call.invoke( new Object[] { textToSend } );
System.out.println("You typed : " + ret);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
deploy.wsdd/undeploy.wsdd
deploy.wsdd
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
>
<service name="MyService" provider="java:RPC">
<parameter name="className"
value="ej3customdeployment.MyService"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
undeploy.wsdd
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="MyService"/>
</undeployment>
Mapeos de WSDL a Java
xsd:base64Binary
byte[]
xsd:boolean
boolean
xsd:byte
byte
xsd:dateTime
java.util.Calendar
xsd:decimal
java.math.BigDecimal
xsd:double
double
xsd:float
float
xsd:hexBinary
byte[]
xsd:int
int
xsd:integer
java.math.BigInteger
xsd:long
long
xsd:QName
javax.xml.namespace.QName
xsd:short
short
xsd:string
java.lang.String
Pasando Objetos en Servicios
Web
Las excepciones se representan como elementos wsdl:fault
Podemos pasar objetos como argumentos con la ayuda del elemento
del elemento beanmapping en un .wsdd
<beanMapping qname="ns:local" xmlns:ns="someNamespace"
languageSpecificType="java:my.java.thingy"/>
Revisar ejemplo:
samples/userguide/example5/BeanService.java
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/ja
va">
<service name="OrderProcessor" provider="java:RPC">
<parameter name="className"
value="samples.userguide.example5.BeanService"/>
<parameter name="allowedMethods"
value="processOrder"/>
<beanMapping qname="myNS:Order"
xmlns:myNS="urn:BeanService"
languageSpecificType="java:samples.userguide.example5.Or
der"/>
</service>
</deployment>
Pasando Objetos en Servicios
Web
Dado que el BeanSerializer no permite
transformar clases ya existentes que no conformen
con el estándar JavaBean, es posible utilizar custom
serialization
Para ello en el wsdd colocaremos:
<typeMapping qname="ns:local"
xmlns:ns="someNamespace"
languageSpecificType="java:my.java.thingy"
serializer="my.java.Serializer"
deserializer="my.java.DeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/so
ap/encoding/"/>
Web Services Description
Language (WSDL)
Si miramos al fichero WSDL encontraremos:
service que describe el servicio web
Elementos operation que documentan las
operaciones
Elementos binding que documentan los
protocolos soportados por el servicio web
Etc.
Elemento
Para publicar un servicio web deberemos
publicar su contrato, WSDL.
Otros
desarrolladores pueden utilizar el contrato
para desarrollar clientes web
Nomalmente procesan el fichero WSDL a través
de una herramienta que genera clases wrapper
Usando WSDL con Axis
Web Service Description Language (WSDL) permite describir los
servicios web de una manera estructurada
Un WSDL nos da la siguiente información:
La interfaz al servicio
Los parámetros que acepta
La localización del servicio
AXIS soporta WSDL de tres formas:
Podemos obtener el wsdl de un servicio accediendo a su URL en un
navegador y colocando el sufijo ?wsdl
http://localhost:8080/axis/Echo.jws?wsdl
Herramienta WSDL2Java que genera Java proxies y skeletons a partir
de descriptores WSDL
Herramienta Java2WSDL que construye WSDL a partir de clases Java
WSDL2Java: proxies, stubs y
tipos de datos
Esta herramienta es disponible en la
clase:
org.apache.axis.wsdl.WSDL2Java
Su uso sería:
java org.apache.axis.wsdl.WSDL2Java
(WSDL-file-URL)
Existe la tarea wsdl2java en Ant
WSDL2Java
WSDL clause
Java class(es) generated
For each entry in the type section
A java class
A holder if this type is used as an inout/out parameter
For each portType
A java interface
For each binding
A stub class
For each service
A service interface
A service implementation (the locator)
Mapeo Tipos
<xsd:complexType name="phone">
<xsd:all>
<xsd:element name="areaCode" type="xsd:int"/>
<xsd:element name="exchange" type="xsd:string"/>
<xsd:element name="number" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
Mapearía a:
public class Phone implements java.io.Serializable {
public Phone() {...}
public int getAreaCode() {...}
public void setAreaCode(int areaCode) {...}
public java.lang.String getExchange() {...}
public void setExchange(java.lang.String exchange) {...}
public java.lang.String getNumber() {...}
public void setNumber(java.lang.String number) {...}
public boolean equals(Object obj) {...}
public int hashCode() {...}
}
Mapeo Parámetros de
Entrada/Salida
package samples.addr.holders;
public final class PhoneHolder implements
javax.xml.rpc.holders.Holder {
public samples.addr.Phone value;
public PhoneHolder()
{
}
public PhoneHolder(samples.addr.Phone value) {
this.value = value;
}
}
Mapeo PortTypes
<message name="empty">
<message name="AddEntryRequest">
<part name="name" type="xsd:string"/>
<part name="address" type="typens:address"/>
</message>
<portType name="AddressBook">
<operation name="addEntry">
<input message="tns:AddEntryRequest"/>
<output message="tns:empty"/>
</operation>
</portType>
Mapearía a:
public interface AddressBook extends java.rmi.Remote {
public void addEntry(String name, Address address) throws
java.rmi.RemoteException;
}
Mapeo Bindings
Su nombre es el nombre del Binding con el sufijo Stub
Implementa el SDI (Service Description Interface)
Actúa como un proxy entre el cliente y el servicio web
El stub esconde el endpoint, namespace, o los arrays de parámetros
Así el siguiente fragmento de wsdl generaría:
<binding name="AddressBookSOAPBinding" type="tns:AddressBook"> ... </binding>
Lo siguiente:
public class AddressBookSOAPBindingStub extends org.apache.axis.client.Stub
implements AddressBook {
public AddressBookSOAPBindingStub() throws org.apache.axis.AxisFault
{...}
public AddressBookSOAPBindingStub(URL endpointURL,
javax.xml.rpc.Service service)
throws org.apache.axis.AxisFault
{...}
public AddressBookSOAPBindingStub(javax.xml.rpc.Service service)
throws org.apache.axis.AxisFault
{...}
public void addEntry(String name, Address address) throws RemoteException
{...}
}
Servicios
Normalmente un cliente instanciará un localizador de servicios y luego llamará al método
get para recuperar su stub.
Se deriva del elemento service de WSDL:
<service name="AddressBookService">
<port name="AddressBook" binding="tns:AddressBookSOAPBinding">
<soap:address
location="http://localhost:8080/axis/services/AddressBook"/>
</port>
</service>
Como:
public interface AddressBookService extends javax.xml.rpc.Service {
public String getAddressBookAddress();
public AddressBook getAddressBook() throws
javax.xml.rpc.ServiceException;
public AddressBook getAddressBook(URL portAddress) throws
javax.xml.rpc.ServiceException;
}
WSDL2Java will also generate the locator which implements this interface:
public class AddressBookServiceLocator extends org.apache.axis.client.Service
implements AddressBookService {
...
Uso del Service Locator
public class Tester
{
public static void main(String [] args) throws Exception {
// Make a service
AddressBookService service = new
AddressBookServiceLocator();
SDI.
// Now use the service to get a stub which implements the
AddressBook port = service.getAddressBook();
// Make the actual call
Address address = new Address(...);
port.addEntry("Russell Butek", address);
}
}
Bindings en la Parte Servidora:
Skeleton
Stub es el proxy en el cliente de un Servicio
Web
El Skeleton es el proxy del Servicio Web en el
servidor
Necesitas especificar los flags --server-side
--skeletonDeploy true" cuando invocas
WSDL2java:
java org.apache.axis.wsdl.WSDL2Java -server-side --skeletonDeploy true
AddressBook.wsdl
Bindings en la Parte Servidora:
Skeleton
WSDL clause
For each binding
Java class(es) generated
A skeleton class
An implementation template class
For all services
One deploy.wsdd file
One undeploy.wsdd file
Los Skeleton
Intermediario entre el Axis engine y la
implementación del servicio
Su nombre es el del binding con el sufijo
Skeleton
Compilación Ejemplo ej4wsdl2java
Los pasos a seguir serían:
java
org.apache.axis.wsdl.WSDL2Java -server-side AddressBook.wsdl
cd AddressFetcher2
javac *.java
java org.apache.axis.client.AdminClient
deploy.wsdd
Herramienta Java2WSDL
1.
Crear una interfaz Java o una clase que describa la
interfaz del servicio web. Por ejemplo:
package ej5java2wsdl;
public interface MyWidgetPrice {
public void setWidgetPrice(String
widgetName, String price);
public String getWidgetPrice(String
widgetName);
}
Herramienta Java2WSDL
2.
Crear el WSDL por medio de Java2WSDL
Para crear el WSDL asociado a la clase anterior haríamos:
java org.apache.axis.wsdl.Java2WSDL -o wp.wsdl l"http://localhost:8080/axis/services/MyWidgetPr
ice" -n "urn:Example6" -p"ej5java2wsdl"
"urn:Example6" ej5java2wsdl.MyWidgetPrice
donde:
-o indica el nombre del fichero WSDL de salida
-l denota la localización del servicio
-n es el espacio de nombres de destino del fichero WSDL
-p indica un mapeo del paquete al espacio de nombres.
la clase que contiene la interfaz del servicio web.
Para más información sobre Java2WSDL revisar
http://ws.apache.org/axis/java/reference.html
Java2WSDL
3.
Utilizar WSDL2Java para generar los bindings
El comando:
java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s
-S true -Nurn:Example6 ej5java2wsdl wp.wsdl
Generaría:
WidgetPriceSoapBindingImpl.java : fichero Java conteniendo la
implementación por defecto de la parte servidora del servicio web Web
Service
Habrá que modificar esta clase para añadir tu implementación
WidgetPrice.java: nueva interfaz que contiene los java.rmi.Remote
apropiados
WidgetPriceService.java: fichero que contiene la interfaz de la
parte cliente
WidgetPriceServiceLocator.java: fichero conteniendo la
implementación de la parte cliente del servicio
WidgetPriceSoapBindingSkeleton.java: el skeleton de la parte
servidora
WidgetPriceSoapBindingStub.java: el stub de la parte cliente
deploy.wsdd: descriptor de explotación
undeploy.wsdd: descriptor de desesplotación
Tipos de datos: ficheros correspondientes a los tipos y holders del
servicio web
Servicios Web de Consumo
Público
Acceder a la url:
http://www.xmethods.net
Generar la parte cliente del servicio web
con el comando WSDL2Java
Tareas Ant para Construir
Ejemplos
Las siguientes tareas en Ant simplifican la compilación y
despliegue de servicios web:
<axis-wsdl2java>
<axis-java2wsdl>
<axis-admin>
Para más información mirar en:
http://ws.apache.org/~toshi/jp-site/axis/java/ant/ant.html
Revisar ejemplo
samples\userguide\example6\build.xml
Cliente Calculadora en .NET
Vamos a realizar un cliente para nuestro
Servicio Web calculadora en .NET:
wsdl
http://localhost:8080/axis/Calculator.j
ws?wsdl
Escribimos fichero Calculadora.cs
csc CalculatorService.cs Calculadora.cs
Ejecutamos: Calculadora.exe
Calculadora.cs
using System;
class Calculadora
{
public static void Main ()
{
CalculatorService calc = new CalculatorService ();
int sum = calc.add (2, 2);
Console.WriteLine ("2 + 2 = " + sum);
int resta = calc.subtract (2, 2);
Console.WriteLine ("2 - 2 = " + resta);
}
}
Cliente Calculadora en Java
Pasos de desarrollo:
1.
2.
3.
4.
java
org.apache.axis.wsdl.WSDL2Java
http://localhost:8080/axis/Calcu
lator.jws?wsdl
Escribir clase CalcClient
Compilarla: javac CalcClient
Ejecutarla: java CalcClient
Cliente Calculadora en Java
import localhost.axis.Calculator_jws.*;
public class CalcClient
{
public static void main(String [] args) throws Exception {
// Make a service
CalculatorService service = new CalculatorServiceLocator();
// Now use the service to get a stub which implements the SDI.
Calculator port = service.getCalculator();
// Make the actual call
int sum = port.add(2,2);
System.out.printf("2+2=%d\n", sum);
int resta = port.subtract(2,2);
System.out.printf("2-2=%d\n", resta);
}
}