Diferencia entre revisiones de «Usuario:ManuelRomero/ProgramacionWeb/WS/soap»

De WikiEducator
Saltar a: navegación, buscar
 
(9 revisiones intermedias por el mismo usuario no mostrado)
Línea 1: Línea 1:
__TOC__
+
{{TEP}}
===SOAP '''Simple Object Access Protocol''' ===
+
{{:Usuario:ManuelRomero/dwes/SOAP/nav}}
*Es un protocolo que indica cómo se tienen que intercambiar mensajes entre cliente y servidor.
+
  https://www.whoishostingthis.com/resources/soap/
*Utiliza '''''xml''''' para este intercambio
+
  https://velneo.es/velneo-los-web-services/
*'''''SOAP''''' se acompaña de un lenguaje llamada '''''WSDL''''' '''Web Service Description Lenguage, usado para describir y publicar las funciones que el servicio ofrece a sus clientes.
+
  https://www.youtube.com/watch?v=KSic3tppmTc
*A continuación vamos a entender y profundizar en las diferentes partes de un fichero ''xml'' de soap para poder entenderlo
+
====Fichero xml que soap crea para el intercambio====
+
Un mensaje '''''SOAP''''' viaja en un fichero ''xml'' con la siguiente estructura.
+
La información del siguiente fichero es simplemente informativa, no es necesaria su compresión para un uso profesional de esta forma de usar (crear y/o consumir) servicios web basados en SOAP.
+
 
+
#Elemento principal o '''''Envelope''''' o elemento raiź  que identifica el mensaje
+
#cabecera o header opcional. se componen de uno o varios '''''header blocks'''''; cada uno de ellos detalla como se debe procesar el mensaje
+
#body : Es una parte obligatoria, y  contiene la información relativa a la llamada y la respuesta.
+
[[Archivo:xmlSoap1.png]]
+
En el elemento Envelope se especifica la versión de soap
+
*En la version 1.1
+
<source lang=xml>
+
<soap:Envelope
+
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
+
  soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+
</source>
+
*En la versión 1.2
+
<source lang=xml>
+
<soap:Envelope
+
  xmlns:soap=http://www.w3.org/2003/05/soap-envelope/"
+
  http://www.w3.org/2003/05/soap-encoding/">
+
</source>
+
La gestión de este fichero, tanto el hecho de crearlo para responder a una solicitud como la tarea de leerlo e interpretarlo, sería un labor tediosa. Existen librerías en los diferentes lenguajes de programación que automatizan este proceso. Para php vamos a ver PHP5 SOAP, disponible a partir de la versión 5
+
 
+
'''''PHP5 SOAP''''' es la implementación de SOAP que se incluye con PHP a partir de la versión 5 del lenguaje. En versiones anteriores se tenía que recurrir a otras opciones para trabajar con SOAP. Es una extensión nativa (escrita en lenguaje C) y por tanto más rápida que otras posibilidades (NuSOAP -http://code.google.com/p/nusoap-for-php5/- o PEAR::SOAP --). Como veremos más adelante, su gran inconveniente es que no permite la generación automática del documento WSDL una vez programado el servidor SOAP correspondiente.
+
 
+
====Describir un servicio====
+
*Consiste es publicar qué funciones ofrece mi servicio web, así como qué parámetros necesita y que valor/es retorna dicha función.
+
*Este paso es importante sobre todo si no es la personas que ha desarrollado el servicio la  única que va a utilizarlo.
+
*En ''SOAP'' esto se hace usando el leguaje de descrición '''''WSDL''''' ''(Lenguaje de Descripción de Servicios Web)''.
+
 
+
'''''WSDL''''' es un lenguaje basado en ''xml'' que utiliza unas reglas determinadas para generar el documento de descripción de un servicio web.
+
*Una vez generado, ese documento se suele poner a disposición de los posibles usuarios del servicio (normalmente se accede al documento WSDL añadiendo ?wsdl a la URL del servicio).
+
 
+
*En la siguiente imagen podemos ver las diferentes partes de un fichero xml wsdl.
+
*Podemos observar como cambia según estemos en la version 1.1 o la versión 2.
+
 
+
[[Archivo:wsdlMRM.png]]
+
 
+
;types y message
+
*En la versión 2 solo existe el elemento types
+
*Describe las definiciones de tipos de datos que se usan en el servicio, como lista de parámetros que recibe una función o los valores que retorna
+
;portType o interfaces
+
Cada uno de estos elementos es cada una de las funciones que el servicio ofrece
+
Cada función se define es una '''operation''' con sus '''input''' y '''output''' como podemos ver en la imagen
+
;binding
+
*Define como va a transmitirse la información de cada '''''portType'''''
+
;service
+
*Contiene una lista de las diferentes url (1 o varias) en donde se puede acceder al servicio web
+
*Definir, construir e interpretar el contenido de un fichero '''wsdl''', puede ser de nuevo una tarea de gran calibre
+
*En lugar de hacerlo, usaremos herramientas que nos construyan este  fichero como vamos a ver a continuación
+
*Todo esto no tenemos que gestionarlo directamente. Posteriormente veremos como generamos el fichero wsdl a partir del servicio que queremos ofrecer, usando una librería.
+
===PHP SOAP===
+
*Para implementar un servicio web vamos a usar esta extensión nativa de '''''php'''''.
+
*Primero verificamos que la tenemos instalada
+
*Ejecutamos un phpinfo() y buscamos la sección de soap
+
[[Archivo:phpSoap.png]]
+
*Esta extensión nos permite usar dos clases importantes SoapClient (para comunicarnos con un servicio web) y SoapServer (para crear un propio servicio web).
+
En caso de no ternerla instalada podemos hacerlo desde el repositorio de ubuntu, dependiendo de la versión
+
<source lang=bash>
+
sudo apt-get install php-soap
+
sudo apt-get install php7.0-soap
+
</source>.
+
===Trabajando con Soap===
+
{{MRM_Actividad| Title="Trabajando con Soap"|
+
'''A continuación vamos a realizar una serie de acciones con el servicio web:'''
+
;1.- Usar o consumir un servicio web basado en SOAP que alguien ha implementado
+
;2.- Crear y consumir un servicio web que creemos nosotros mismos sin usar fichero wsdl
+
;3.- Crear y consumir un servicio web que creemos nosotros mismos usando fichero wsdl. Esto nos permitiría publicarlo
+
}}
+
 
+
====Consumiendo un servicio web====
+
;Lo primero que tenemos que hacer es localizar y entender el servicio que queremos utilizar.
+
<br/>
+
=====Localizando un servicio=====
+
<br />
+
{{MRM_Actividad|Usar un servicio web de webservicex para la conversión de dólares a euros }}
+
*Vamos a usar un servicio web mediante el protocolo o estándar SOAP.
+
*Suponemos que queremos tener de forma actualizada la conversión de euros a doláres y viceversa.
+
*En lugar de hacerlo a mano queremos una actualización en el momento de calcular un precio, y para ello vamos a usar un servicio disponible en WebSeviceX.net (http://www.webservicex.net/ws/default.aspx).
+
*En la página podemos ver varios servicios, usaremos el de Currency Convertor  (http://www.webservicex.net/ws/WSDetails.aspx?CATID=2&WSID=10).
+
 
+
*Dentro de la página localizamos el fichero descriptor wsdl del servicio
+
http://www.webservicex.net/CurrencyConvertor.asmx?WSDL
+
*Si escribimos esta url, aparecerá el contenido del fichero
+
*A partir de este fichero podemos deducir la siguiente información:
+
;1.- El alias del espacio de nombres correspondiente al XML Schema que utiliza el documento es'''''s'''''
+
<source lang=xml>
+
<wsdl:definitions
+
...
+
  xmlns:s="http://www.w3.org/2001/XMLSchema"
+
...
+
>
+
</source>
+
;2.-El tipo Currency debe de ser un string de tres caracteres de los que se listan en el documento, correspondiente a las siglas de una divisa.
+
{{Plegable|hide|Tipos de divisa|
+
<source lang=xml>
+
....
+
<s:simpleType name="Currency">
+
<s:restriction base="s:string">
+
<s:enumeration value="AFA"/>
+
<s:enumeration value="ALL"/>
+
<s:enumeration value="DZD"/>
+
<s:enumeration value="ARS"/>
+
<s:enumeration value="AWG"/>
+
<s:enumeration value="AUD"/>
+
<s:enumeration value="BSD"/>
+
<s:enumeration value="BHD"/>
+
<s:enumeration value="BDT"/>
+
<s:enumeration value="BBD"/>
+
<s:enumeration value="BZD"/>
+
<s:enumeration value="BMD"/>
+
<s:enumeration value="BTN"/>
+
<s:enumeration value="BOB"/>
+
<s:enumeration value="BWP"/>
+
<s:enumeration value="BRL"/>
+
<s:enumeration value="GBP"/>
+
<s:enumeration value="BND"/>
+
<s:enumeration value="BIF"/>
+
<s:enumeration value="XOF"/>
+
<s:enumeration value="XAF"/>
+
<s:enumeration value="KHR"/>
+
<s:enumeration value="CAD"/>
+
<s:enumeration value="CVE"/>
+
<s:enumeration value="KYD"/>
+
<s:enumeration value="CLP"/>
+
<s:enumeration value="CNY"/>
+
<s:enumeration value="COP"/>
+
<s:enumeration value="KMF"/>
+
<s:enumeration value="CRC"/>
+
<s:enumeration value="HRK"/>
+
<s:enumeration value="CUP"/>
+
<s:enumeration value="CYP"/>
+
<s:enumeration value="CZK"/>
+
<s:enumeration value="DKK"/>
+
<s:enumeration value="DJF"/>
+
<s:enumeration value="DOP"/>
+
<s:enumeration value="XCD"/>
+
<s:enumeration value="EGP"/>
+
<s:enumeration value="SVC"/>
+
<s:enumeration value="EEK"/>
+
<s:enumeration value="ETB"/>
+
<s:enumeration value="EUR"/>
+
<s:enumeration value="FKP"/>
+
<s:enumeration value="GMD"/>
+
<s:enumeration value="GHC"/>
+
<s:enumeration value="GIP"/>
+
<s:enumeration value="XAU"/>
+
<s:enumeration value="GTQ"/>
+
<s:enumeration value="GNF"/>
+
<s:enumeration value="GYD"/>
+
<s:enumeration value="HTG"/>
+
<s:enumeration value="HNL"/>
+
<s:enumeration value="HKD"/>
+
<s:enumeration value="HUF"/>
+
<s:enumeration value="ISK"/>
+
<s:enumeration value="INR"/>
+
<s:enumeration value="IDR"/>
+
<s:enumeration value="IQD"/>
+
<s:enumeration value="ILS"/>
+
<s:enumeration value="JMD"/>
+
<s:enumeration value="JPY"/>
+
<s:enumeration value="JOD"/>
+
<s:enumeration value="KZT"/>
+
<s:enumeration value="KES"/>
+
<s:enumeration value="KRW"/>
+
<s:enumeration value="KWD"/>
+
<s:enumeration value="LAK"/>
+
<s:enumeration value="LVL"/>
+
<s:enumeration value="LBP"/>
+
<s:enumeration value="LSL"/>
+
<s:enumeration value="LRD"/>
+
<s:enumeration value="LYD"/>
+
<s:enumeration value="LTL"/>
+
<s:enumeration value="MOP"/>
+
<s:enumeration value="MKD"/>
+
<s:enumeration value="MGF"/>
+
<s:enumeration value="MWK"/>
+
<s:enumeration value="MYR"/>
+
<s:enumeration value="MVR"/>
+
<s:enumeration value="MTL"/>
+
<s:enumeration value="MRO"/>
+
<s:enumeration value="MUR"/>
+
<s:enumeration value="MXN"/>
+
<s:enumeration value="MDL"/>
+
<s:enumeration value="MNT"/>
+
<s:enumeration value="MAD"/>
+
<s:enumeration value="MZM"/>
+
<s:enumeration value="MMK"/>
+
<s:enumeration value="NAD"/>
+
<s:enumeration value="NPR"/>
+
<s:enumeration value="ANG"/>
+
<s:enumeration value="NZD"/>
+
<s:enumeration value="NIO"/>
+
<s:enumeration value="NGN"/>
+
<s:enumeration value="KPW"/>
+
<s:enumeration value="NOK"/>
+
<s:enumeration value="OMR"/>
+
<s:enumeration value="XPF"/>
+
<s:enumeration value="PKR"/>
+
<s:enumeration value="XPD"/>
+
<s:enumeration value="PAB"/>
+
<s:enumeration value="PGK"/>
+
<s:enumeration value="PYG"/>
+
<s:enumeration value="PEN"/>
+
<s:enumeration value="PHP"/>
+
<s:enumeration value="XPT"/>
+
<s:enumeration value="PLN"/>
+
<s:enumeration value="QAR"/>
+
<s:enumeration value="ROL"/>
+
<s:enumeration value="RUB"/>
+
<s:enumeration value="WST"/>
+
<s:enumeration value="STD"/>
+
<s:enumeration value="SAR"/>
+
<s:enumeration value="SCR"/>
+
<s:enumeration value="SLL"/>
+
<s:enumeration value="XAG"/>
+
<s:enumeration value="SGD"/>
+
<s:enumeration value="SKK"/>
+
<s:enumeration value="SIT"/>
+
<s:enumeration value="SBD"/>
+
<s:enumeration value="SOS"/>
+
<s:enumeration value="ZAR"/>
+
<s:enumeration value="LKR"/>
+
<s:enumeration value="SHP"/>
+
<s:enumeration value="SDD"/>
+
<s:enumeration value="SRG"/>
+
<s:enumeration value="SZL"/>
+
<s:enumeration value="SEK"/>
+
<s:enumeration value="CHF"/>
+
<s:enumeration value="SYP"/>
+
<s:enumeration value="TWD"/>
+
<s:enumeration value="TZS"/>
+
<s:enumeration value="THB"/>
+
<s:enumeration value="TOP"/>
+
<s:enumeration value="TTD"/>
+
<s:enumeration value="TND"/>
+
<s:enumeration value="TRL"/>
+
<s:enumeration value="USD"/>
+
<s:enumeration value="AED"/>
+
<s:enumeration value="UGX"/>
+
<s:enumeration value="UAH"/>
+
<s:enumeration value="UYU"/>
+
<s:enumeration value="VUV"/>
+
<s:enumeration value="VEB"/>
+
<s:enumeration value="VND"/>
+
<s:enumeration value="YER"/>
+
<s:enumeration value="YUM"/>
+
<s:enumeration value="ZMK"/>
+
<s:enumeration value="ZWD"/>
+
<s:enumeration value="TRY"/>
+
</s:restriction>
+
</s:simpleType>
+
.......
+
</source>
+
}}
+
;3 Este servicio se usa invocando a un método llamado '''''ConversionRate''''', que recibe un parámetro que usado en php será un array asociativo con dos campos: el campo '''''FromCurrency''''' y el campo '''''ToCurrency''''', cuyos valores serán uno de los permitidos expuestos anteriormente. Un ejemplo de uso debería ser algo parecido a  lo siguiente
+
<source lang=php>
+
...
+
$parametros=["FromCurrency"=>"USD", "ToCurrency"=>"EUR"];
+
$retorno = ConversionRate($parametros);
+
.....
+
</source>
+
{{Plegable|hide|Método que ofrece el servicio|
+
<source lang=xml>
+
<s:element name="ConversionRate">
+
<s:complexType>
+
<s:sequence>
+
<s:element minOccurs="1" maxOccurs="1" name="FromCurrency" type="tns:Currency"/>
+
<s:element minOccurs="1" maxOccurs="1" name="ToCurrency" type="tns:Currency"/>
+
</s:sequence>
+
</s:complexType>
+
</s:element>
+
</source>
+
}}
+
4.-'''''ConversionRateResponse''''' es una clase con un atributo '''ConversionRateResult''' el cual es un double. Este es el valor que retornará el método del servicio de convertir.
+
Por lo que siguiente con el uso anterior para visualizar el resultado deberíamos de hacer algo parecidio a esto:
+
 
+
<source lang=php>
+
...
+
$parametros=["FromCurrency"=>"USD", "ToCurrency"=>"EUR"];
+
 
+
 
+
$retorno = ConversionRate($parametros);
+
//$retorno será un objeto de la clase ConversionRateResponse
+
 
+
$valor = $retorno->ConversionRateResult;
+
echo "El valor de un dólar USD es de $valor Euros";
+
.....
+
 
+
</source>
+
{{Plegable|hide|Tipo que devuelve el servicio|
+
<source lang=xml>
+
<s:element name="ConversionRateResponse">
+
<s:complexType>
+
  <s:sequence>
+
    <s:element
+
        minOccurs="1" maxOccurs="1"
+
        name="ConversionRateResult" type="s:double"
+
    />
+
  </s:sequence>
+
</s:complexType>
+
</s:element>
+
</source>
+
}}
+
*En resumen tenemos la siguiente información
+
{{MRM_Resumen|
+
<source lang=php>
+
función :  ConversionRate
+
parámetros : array ("FromCurrency" =>"XXX", "ToCurrenci"=>"XXX");
+
valor que retorna : ConversionRateResponse que tiene un atributo ConversionRateResult que es un float.
+
</source>
+
}}
+
 
+
=====Escribiendo el código=====
+
*Ahora vamos a escribir el código php para usar este servicio
+
*Primero creamos un objeto de la clase '''''SoapClient'''''
+
 
+
*El objeto de la clase ''SoapClient'', necesita en el constructor la ubiación del fichero '''''wsdl'''''
+
(Luego veremos que también puede ser valor null, y especificarlo posteriormente
+
<source lang=php>
+
    $cliente = new SoapClient(  "http://www.webservicex.net/CurrencyConvertor.asmx?WSDL");
+
</source>
+
*Es interesante usar alguno de los métodos que tiene esta clase, que nos da información interesante.
+
*Aquí puedes echar un vistazo a todas
+
http://php.net/manual/es/class.soapclient.php
+
*En varias ocasiones interesa mirar __getFunctions y __getTypes que nos dicen los métodos que ofrece el servicio y los parámetros que se utilizan.
+
 
+
*Ahora a continuación vamos a realizar la llamada a la función de conversión que ofrece este servicio
+
*La función se llama '''''ConversionRate''''' como podemos ver en el elemento descrito anteriormente. Esta funcion recibe como parámetro un array asociativo con dos valores
+
*En este calso queremos pasar de Euros a Dólares
+
<source lang=php>
+
  $parametros = array("FromCurrency" => "EUR", "ToCurrency" => "USD");
+
  $tasa = $cliente->ConversionRate($parametros);
+
</source>
+
 
+
*Y ahora solo queda capturar el resultado y visualizarlo
+
<source lang=php>
+
  print("Resultado: ".$tasa->ConversionRateResult);
+
</source>
+
{{MRM_Actividad|Title=Conversión de monedas|
+
*Realiza una aplicación que permita convertir catidades de dinero de un tipo de moneda a otra
+
*El usuario deberá seleccionar una cantidad de dinero en un tipo de moneda y el tipo de moneda a la que quiere convertir
+
*Al final obtendrá la cantidad de dinero que es en esa moneda
+
    105 USA son 124 EUR
+
{{Tip|Para el sigueinte ejemplo, previamente tendremos un fichero llamado monedas.txt que contendrá las siglas de las monedas y su texto separado por un guión
+
<source lang=bash>
+
ALL-Albanian Lek
+
DZD-Algerian Dinar
+
ARS-Argentine Peso
+
AWG-Aruba Florin
+
AUD-Australian Dollar
+
BSD-Bahamian Dollar
+
BHD-Bahraini Dinar
+
</source>
+
Se pueden copiar de aquí
+
http://www.webservicex.net/New/Home/ServiceDetail/10
+
}}
+
{{Plegable|hide|Adaptación de conversión de monedas|
+
<source lang=php>
+
<?php
+
 
+
$f = fopen("monedas.txt", "r");
+
while (!feof($f)) {
+
  $fila = fgets($f);
+
  $conversion = explode("-", $fila);
+
  $monedas[$conversion[0]] = $conversion[1];
+
}
+
 
+
$cliente = new SoapClient("http://www.webservicex.net/CurrencyConvertor.asmx?WSDL");
+
 
+
$parametros = array("FromCurrency" => "EUR", "ToCurrency" => "USD");
+
$tasa = $cliente->ConversionRate($parametros);
+
print("Resultado: " . $tasa->ConversionRateResult);
+
 
+
 
+
echo "<select name=from>";
+
foreach ($monedas as $sigla => $detalle) {
+
  echo "<option value=$sigla>$detalle</options>";
+
}
+
echo "</select>";
+
 
+
echo "<select name=to>";
+
foreach ($monedas as $sigla => $detalle) {
+
  echo "<option value=$sigla>$detalle</options>";
+
}
+
echo "</select>";
+
?>
+
</source>
+
}}
+
}}
+
=====Usar un servicio creando la clase del servicio=====
+
*Es posible para mayor comodidad crear una clase del servicio en mi desarrollo local, y posteriormente usar esta clase como si fuera un desarrollo local.
+
*Es decir, en el ejemplo anterior tener una clase llamada ConversionRate.php que contenga los métodos disponibles en el servicio.
+
*En este caso la forma de utilizar el servicio debería quedar algo parecido al siguiente código
+
<source lang=php>
+
<?php
+
 
+
?>
+
</source>
+
*Para construir la clase del servicio, usaremos herramientas disponibles del tipo '''''wsdl2php'''''. Se trata de construir la clase a partir de la información que tenemos en el fichero wsdl.
+
*Podemos descargar este proyecto y usarlo
+
"https://github.com/wsdl2phpgenerator/wsdl2phpgenerator/releases/download/2.3.0/wsdl2phpgenerator-2.3.0.phar"
+
*En este ejemplo, vamos a utilizar una utilidad on line
+
http://www.stccorp.net/ewsdl2php/
+
*Aquí debemos escribir el url del fichero wsdl y obtendremos la clase
+
*Si escribimos la url en la ubicación especificada y escribimos un nombre de clase
+
[[Archivo:wsdltophp_parametros.png|400px|center]]<br />
+
{{Plegable|hide|Clase obtenida a partir del fichero wsdl|
+
<source lang=php>
+
 
+
<?php
+
//....
+
 
+
$cliente = new ConversinoRate();
+
...
+
$
+
 
+
 
+
 
+
class ConversionRate{
+
var $FromCurrency;//Currency
+
var $ToCurrency;//Currency
+
}
+
 
+
class ConversionRateResponse{
+
var $ConversionRateResult;//double
+
}
+
 
+
class CurrencyConvertor
+
{
+
var $soapClient;
+
+
private static $classmap = array('ConversionRate'=>'ConversionRate'
+
,'ConversionRateResponse'=>'ConversionRateResponse'
+
 
+
);
+
 
+
function __construct($url='http://www.webservicex.net/CurrencyConvertor.asmx?WSDL') {
+
  $this->soapClient = new SoapClient($url,array("classmap"=>self::$classmap,"trace" => true,"exceptions" => true));
+
}
+
+
function ConversionRate(ConversionRate $ConversionRate){
+
 
+
$ConversionRateResponse = $this->soapClient->ConversionRate($ConversionRate);
+
return $ConversionRateResponse;
+
 
+
}
+
function ConversionRate(ConversionRate $ConversionRate){
+
 
+
$ConversionRateResponse = $this->soapClient->ConversionRate($ConversionRate);
+
return $ConversionRateResponse;
+
 
+
}
+
 
+
}
+
 
+
 
+
?>                               
+
                           
+
</source>
+
}}
+
 
+
 
+
====Crear un consumir un serivcio Soap sin wsdl====
+
*Ahora vamos a crear un servicio soap.
+
Cuando creamos un servicio para usarlo nosotras/os mimas/os, en realidad no necesitamos el fichero '''''wsdl''''' que al fin y al cabo no es más que un docuemnto que informa de los métodos que ofrecemos, los parámetros que necesita, así como del tipo de valor que devuelve, si es el caso.
+
*En ese caso en realidad no necesitamos crear ni usar el fichero wsdl
+
 
+
 
+
*En el segundo caso, si no indicas en el constructor un documento WSDL (bien porque no existe, o porque necesitas configurar manualmente alguna opción), el primer parámetro debe ser null, y las opciones para comunicarse con el servicio las tendrás que establecer en un array que se pasa como segundo parámetro.
+
 
+
*Si el fichero '''''wsdl''''' existe, puedes usar una herramienta (hay varias), que te conviertan el fichero wsdl a php e incluirlo en tu fichero php
+
*En este caso vamos a usar la herramienta wsdl2php http://www.urdalen.no/wsdl2php/index.php
+
*Una vez descargado el fichero lo instalamos *Descargamos el fichero http://sourceforge.net/projects/wsdl2php/files/latest/download
+
en línea de comandos
+
sudo pear install wsdl2php-0.2.1-pear.tgz
+
*Y ahora  con la ubicación del fichero wsdl generamos el php
+
wsdl2php http://www.webservicex.net/CurrencyConvertor.asmx?WSDL
+
*Analiza y genera el fichero php que podemos ver con información clara y completa
+
 
+
*En caso de usar php 7, esta herramienta no funciona. Buscamos otras en la red.
+
*Podemos descargar o usar en la web http://www.stccorp.net/ewsdl2php/ la herramienta ewsdl2php
+
{{MRM_Recursos de la Web|Title= Descarga easyWsdl|
+
https://sourceforge.net/projects/easywsdl2php/<nowiki>?source=typ_redirect</nowiki>
+
}}
+
{{Tip|En caso de descargar  la herramienta, revisa el código php, pues usa etiquetas <? ?> en lugar de <?php ?>, y si no tenemos la directiva correspondiente activada, no funcionará}}
+
 
+
 
+
{{MRM_Actividad|Modifica la práctica anterior usando en este caso una clase creada por tí, y compara la diferencia}}
+
 
+
{{MRM_Actividad|
+
*Inspecciona el servicio disponible en la URL http://www.webservicex.com/globalweather.asmx.
+
*Ofrece información meteorológica sobre distintas ciudades de todo el mundo.
+
* A partir de su documento WSDL, utiliza la herramienta wsdl2php y, partiendo de las clases que ésta genera, crea el código PHP necesario para mostrar las ciudades españolas de las que ofrece información, y la predicción meteorológica para la ciudad de Santiago de Compostela.
+
}}
+
 
+
{{Nota|Tras ejecutar wsdl2php pasándole como parámetro la URL http://www.webservicex.com/globalweather.asmx?wsdl, correspondiente al documento WSDL del servicio web, obtendrás un fichero GlobalWeather.php con las clases correspondientes al servicio. Para ejecutar la consulta al servicio y mostrar la información que se pide, puedes ejecutar un código como el que se propone en la solución al ejercicio.}}
+
 
+
<source lang=php>
+
<?php
+
require_once('GlobalWeather.php');
+
 
+
//Creamos un cliente para llamar a esa URL.
+
$tiempo = new GlobalWeather();
+
//Llamamos a la operación suma (tenemos que saber nosotros que existe)
+
$pais = new GetCitiesByCountry();
+
$pais->CountryName="SPAIN";
+
$ciudades = $tiempo->GetCitiesByCountry($pais);
+
print_r($ciudades);
+
 
+
$ciudad = new GetWeather();
+
$ciudad->CountryName="SPAIN";
+
$ciudad->CityName = "Santiago / Labacolla";
+
 
+
$tiempociudad = $tiempo->GetWeather($ciudad);
+
print_r($tiempociudad);
+
 
+
?>
+
</source>
+
 
+
===Implementado un servicio SOAP===
+
*Ahora vamos a crear un servicio para utilizarlo y ofrecerlo a terceros
+
*Para crear  un servicio web, usaremos la clase ServerSoap, que podemos ver en la imagen siguiente:
+
[[Archivo:SoapServer.jpg|200px]]
+
*Para ello vamos a crear el servicio y luego consumirlo.
+
*En este caso como conocemos las funciones que el servicio ofrece, no necesitamos usar ningún fichero de descripción wsdl
+
*Los pasos a seguir para este cometido son sencillos
+
#Creamos las funciones dque queremos que nuestro servicio ofrezca
+
#Creamos el objeto soapServer
+
#Añadimos las funciones al objeto ServerSoap creado previamente
+
;Creamos las funciones
+
<source lang=php>
+
function sumar($n1, $n2){
+
        return $n1+$n2;
+
}
+
function restar($n1, $n2){
+
        return $n1+$n2;
+
}
+
</source>
+
;Creando el objeto
+
*Para ello debemos establecer el uri del servicio
+
*El objeto constructor tiene dos poarámetros
+
# $ficheroWsdl es el fichero que especifica las funciones que ofrece el servicio. En nuestro caso especificaremos null, pues  no vamos a usar ningún fichero
+
# array asociativo con diferentes posibles valores (ver documentacion http://php.net/manual/es/soapserver.soapserver.php). Nosotros aquí especificaremos la '''''uri'''''
+
<source lang=php>
+
$uri ="localhost/CreandoServicioWeb";
+
$servidor = new SoapServer(null, array('uri'=>$uri));
+
</source>
+
;Añadiendo las funciones que nuestro servicio web ofrece
+
*Ahora solo nos queda añadir las funciones que queremos ofrecer
+
*Para ello usamos el método '''''addFunction(..)''''' de la clase '''''SoapServer'''''
+
<source lang=php>
+
$servidor->addFunction("sumar");
+
$servidor->addFunction("restar");
+
$servidor->handle();
+
</source>
+
*Vemos como al final activamos nuestro servicio con el método manejador o '''''handle'''''
+
;Consumiendo el servicio
+
*Ahora solo nos queda consumir el servicio igual que hicimos en el ejemplo del apartado anterior
+
*Se escribe otro proyecto con el siguiente código, comentarios en el própio código
+
<source lang=php>
+
<?php
+
//Como  no vamos a especificar wsdl, debemos detallar el url donde vamos a consumir el servicio               
+
  $url="http://localhost/CreandoServicioWeb/index.php";
+
  $uri="http://localhost/CreandoServicioWeb/";
+
 
+
//Creamos el cliente con el segundo parámetro. El primero null
+
  $cliente = new SoapClient(null, array('location'=>$url, 'uri'=>$uri));
+
 
+
  $numero = $cliente->sumar(5,4);
+
  echo "valor de la suma ".$numero."<br/>";
+
  $numero = $cliente->restar(5,4);
+
  echo "valor de la resta ".$resta;
+
 
+
?>
+
</source>
+
{{MRM_Actividad| Probar a usar el servicio del compañero y ver que funciona}}
+
*Ahora podemos probar a usar nuestra las operaciones de nuestra calculadora racional como un servicio web.
+
*La idea es que cualquiera pueda hacer operaciones del tipo
+
(a/b op c/d). (op = +|-|*|:)
+
 
+
{{MRM_Actividad| Usando nuestra clase Racional, con el código que facilito, probar a ofrecer el servicio siguiente.
+
sumar ("5/4", "4/5")
+
sumar ("5/4", 4)
+
sumar ("4/5", null)
+
sumar (3, 4) 
+
.....
+
 
+
Igualmente que antes una vez que funciones probamos a que funciones con la compañera/o }}
+
<source lang=php>
+
<?php
+
/**
+
* Description of racional
+
*
+
* @author manolo
+
*/
+
class racional {
+
    //put your code here
+
    private $numRacional;
+
    private $num;
+
    private $den;
+
    public function __construct($cadenaOrNum=null, $den = null) {
+
        if (is_int($cadenaOrNum)){
+
            if (isset($den))
+
                $this->racionalNumDen($cadenaOrNum, $den );
+
            else
+
                $this->racionalNum($cadenaOrNum );
+
        }
+
        else{
+
            if (isset($cadenaOrNum))
+
                $this->racionalCadena($cadenaOrNum);
+
            else
+
                $this->racionalVacio();
+
        }
+
    }
+
   
+
    private function racionalNumDen($num, $den){
+
        $this->numRacional=$num."/".$den;
+
        $this->num=$num;
+
        $this->den=$den;
+
        $this->convierteNum();
+
    }
+
    public function getRacional (){
+
        return $this->numRacional;
+
       
+
    }
+
    private function racionalNum($num){
+
        $this->numRacional=$num."/1";
+
        $this->num=$num;
+
        $this->den=1;
+
        $this->convierteNum();
+
    }
+
    private function racionalCadena($cadenaOrNum){
+
        $this->numRacional=$cadenaOrNum;
+
        $pos = strpos($cadenaOrNum,"/");
+
       
+
        $num=substr($cadenaOrNum,0,$pos);
+
        $den=substr($cadenaOrNum,$pos+1);
+
        $this->num=$num;
+
        $this->den=$den;
+
    }
+
    private function racionalVacio(){
+
        $this->numRacional="1/1";
+
        $this->num=1;
+
        $this->den=1;
+
    }
+
    private function convierteNum(){
+
        settype($this->num, int);
+
        settype($this->den, int);
+
    }
+
+
    public static function sumar(racional $op1, racional $op2){
+
        $num = new Racional($op1->num*$op2->den+$op1->den*$op2->num , $op1->cden*$op2->den);
+
        return  $num;
+
    }
+
 
+
}
+
</source>
+
*Con las siguientes llamadas en cliente
+
<source lang = php>
+
//....
+
  $n1="5/4";
+
  $n2="4/3";
+
  $numero = $cliente->sumar($n1,$n2);
+
  echo "valor de la suma $n1 + $n2 = ".$numero."<br/>";
+
 
+
  $n1="5/4";
+
  $n2=5;
+
  $numero = $cliente->sumar($n1,$n2);
+
  echo "valor de la suma $n1 + $n2 = ".$numero."<br/>";
+
 
+
  $n1=5;
+
  $n2=4;
+
  $numero = $cliente->sumar($n1,$n2);
+
  echo "valor de la suma $n1 + $n2 = ".$numero."<br/>";
+
//...
+
</source>
+
*Se generará la siguiente salida
+
valor de la suma 5/4 + 4/3 = 31/12
+
valor de la suma 5/4 + 5 = 25/4
+
valor de la suma 5 + 4 = 9/1
+
valor de la suma + 3 = 4/1
+
valor de la resta 9
+
*Opcionalmente mejoralo haciendo que en cliente tenga dos cajas de texto para sumandos y una para resultado.
+
 
+
===Creación de un servicio web con fichero wsdl===
+
*Ahora crearemos un servicio web publicando nuestras funciones de nuestro servicio a través del fichero descriptor del servicio wsdl
+
*En dos apartados anteriores estudiamos como era el contenido y la estructura de este documento.
+
*Para el nivel en el que vamos a profundizar, usaremos herramientas para su construcción, pues su conocimiento puede resultar un poco tedioso, aunque si nos dedicáramos a construir servicios con esta tecnología seguro que lo aprenderíamos y sacaríamos buen rendimiento a dichos conocimientos.
+
*En cualquier caso, como veremos a continuación siempre conviene revisar el resultado del fichero wsdl generado de forma automática por algún tipo de software
+
 
+
*Primero debemos actualizar en el fichero '''''php.ini''''' la dierectiva '''''soap.wsdl_cache_enabled = 0''''' si la teníamos a 1. Esto es para que los cambios que hagamos en el fichero wsdl tengan efectos inmediatos. No olvides rebotar el servicio para que la modificación tenga efecto.
+
{{MRM_Puntos clave|
+
#Editar  /etc/php5/apache2/php.ini
+
#modificar directiva  '''''soap.wsdl_cache_enabled <nowiki>=</nowiki> 0'''''
+
#sudo service apache2 restart
+
}}
+
====Creando las funciones a compartir====
+
*A la hora de implementar las funciones que se quieren compartir en el servicio web, se recomienda  crear una clase, e incorporar como métodos las funciones a compartir.
+
*En el ejemplo básico del caso anterior, que queríamos compartir sumar y restar procederíamos del siguiente modo
+
<source lang=php>
+
class Calcula {
+
    public function suma($a, $b){ return $a+$b; }
+
    public function resta($a, $b){ return $a-$b; }
+
}
+
</source>
+
*Ahora para añadir la clase en lugar de '''''addFunction(...)''''', usaríamos '''''setClase(...)'''''
+
<source lang=php>
+
require_once('Calcula.php');
+
$uri = ...;
+
$server = new SoapServer(null, array('uri'=>$uri));
+
$server->setClass('Calcula');
+
$server->handle();
+
</source>
+
{{MRM_Puntos clave|
+
El método setClass recibe como parámetro el nombre de la clase, no el nombre del fichero que implementa la clase
+
'''''$cliente->setClass('Calcula')''''' y no  $cliente->setClass('Calcula.php')}}
+
 
+
====Generando el fichero wsdl====
+
*Para este cometido vamos a usar una herramienta que automatiza el proceso
+
*Como hemos comentado anteriormente conviene revisar el fichero generado
+
*La herramienta se llama wsdlDocument
+
  https://code.google.com/p/wsdldocument/
+
*Primero procedemos a descargarla
+
*Al darle a descagar, se descarga un fichero zip
+
*Este fichero debemos descomprimirlo donde tengamos el proyecto que queramos usar
+
*Posteriormente en el fichero del servidor incluiremos la clase WSDLDocumet.php
+
<source lang=php>
+
require_once ('./WSDLDocument/WSDLDocument.php');
+
....
+
//Generamos un objeto de la clase
+
$wsdl = new WSDLDocument( "MyClass" );
+
 
+
//Hacemos que nos genere el fichero wsdl en formato xml
+
echo $wsdl->saveXml();
+
</source>
+
*Para construir el fichero debemos comentar cada funcion y parámetro que queremos ofrecer en nuestro servidor
+
*Para ello debemos usar el formato PHPDocumentor que es muy parecido al de javaDoc.
+
*Aquí tenemos una referencia
+
http://www.phpdoc.org/
+
*PHPDocumentor es una herramienta de código libre para generación automática de documentación, similar a Javadoc (para el lenguaje Java). Si comentamos el código de nuestras aplicaciones siguiendo unas normas, PHPDocumentor es capaz de generar, a partir de los comentarios que introduzcamos en el código mientras programamos, documentación en diversos formatos (HTML, PDF, XML).
+
*Los comentarios se deben ir introduciendo en el código distribuidos en bloques, y utilizando ciertas marcas específicas como @param para indicar un parámetro y @return para indicar el valor devuelto por una función. Por ejemplo, la clase Calcula  del ejemplo que nos ocupa nos quedaría:
+
<source lang=php>
+
/**
+
* Clase Calcula
+
*
+
* Desarrollo Web en Entorno Servidor
+
* Ejemplo: Documentación para generación
+
*          automática del documento WSDL
+
*/
+
 
+
class Calcula {   
+
    /**
+
    * Suma dos números y devuelve el resultado
+
    *
+
    * @param float $a
+
    * @param float $b
+
    * @return float
+
    */
+
    public function suma($a, $b){
+
        return $a+$b;
+
    }
+
   
+
    /**
+
    * Resta dos números y devuelve el resultado
+
    *
+
    * @param float $a
+
    * @param float $b
+
    * @return float
+
    */
+
    public function resta($a, $b){
+
        return $a-$b;
+
    }
+
}
+
</source>
+
*Ahora nos queda generar el fichero wsdl.
+
*Para ello en el fichero donde creemos el objeto del servicio '''''SoapServer'''', creamos también un objeto de la clase WSDLDocument e indicamos los siguientes documentos:
+
#El nombre de la clase que gestionará las peticiones al servicio.
+
#La URL en que se ofrece el servicio.
+
#El espacio de nombres destino.
+
*El código queda como a continuación se expone:
+
<source lang=php>
+
<?php
+
require_once './WSDLDocument/WSDLDocument.php';
+
require_once 'Calcula.php';
+
 
+
$wsdl = new WSDLDocument( "Calcula",
+
                          "http://localhost/servicioWeb2/index.php",
+
                          "http://localhostg/servicioWeb2/");
+
echo $wsdl->saveXml();
+
 
+
 
+
?>
+
</source>
+
*Una vez que ejecutamos, capturamos la salida de la pantalla y la pegamos en  un fichero (Crtl-u para ver el código de la página web)
+
*Ese es nuestro contenido del fichero wsdl lo copiamos y lo pegamos en un fichero con formato xml
+
*En nuestro caso vemos el código que se genera
+
<source lang=xml>
+
 
+
<?xml version="1.0" encoding="utf-8"?>
+
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://localhostg/servicioWeb2/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhostg/servicioWeb2/">
+
    <wsdl:types>
+
        <xsd:schema targetNamespace="http://localhostg/servicioWeb2/"/>
+
    </wsdl:types>
+
    <wsdl:message name="sumaRequest">
+
        <wsdl:part name="a" type="xsd:float"/>
+
        <wsdl:part name="b" type="xsd:float"/>
+
    </wsdl:message>
+
    <wsdl:message name="sumaResponse">
+
        <wsdl:part name="sumaReturn" type="xsd:float"/>
+
    </wsdl:message>
+
    <wsdl:message name="restaRequest">
+
        <wsdl:part name="a" type="xsd:float"/>
+
        <wsdl:part name="b" type="xsd:float"/>
+
    </wsdl:message>
+
    <wsdl:message name="restaResponse">
+
        <wsdl:part name="restaReturn" type="xsd:float"/>
+
    </wsdl:message>
+
    <wsdl:portType name="CalculaPortType">
+
        <wsdl:operation name="suma">
+
            <wsdl:documentation>Suma dos números y devuelve el resultado</wsdl:documentation>
+
            <wsdl:input message="tns:sumaRequest"/>
+
            <wsdl:output message="tns:sumaResponse"/>
+
        </wsdl:operation>
+
        <wsdl:operation name="resta">
+
            <wsdl:documentation>Resta dos números y devuelve el resultado</wsdl:documentation>
+
            <wsdl:input message="tns:restaRequest"/>
+
            <wsdl:output message="tns:restaResponse"/>
+
        </wsdl:operation>
+
    </wsdl:portType>
+
    <wsdl:binding name="CalculaBinding" type="tns:CalculaPortType">
+
        <soap-env:binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+
        <wsdl:operation name="suma">
+
            <soap-env:operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="http://localhost/servicioWeb2/index.php?method=suma" style="rpc"/>
+
            <wsdl:input>
+
                <soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+
            </wsdl:input>
+
            <wsdl:output>
+
                <soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+
            </wsdl:output>
+
        </wsdl:operation>
+
        <wsdl:operation name="resta">
+
            <soap-env:operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="http://localhost/servicioWeb2/index.php?method=resta" style="rpc"/>
+
            <wsdl:input>
+
                <soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+
            </wsdl:input>
+
            <wsdl:output>
+
                <soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+
            </wsdl:output>
+
        </wsdl:operation>
+
    </wsdl:binding>
+
    <wsdl:service name="Calcula">
+
        <wsdl:documentation>Clase Calcula Desarrollo Web en Entorno Servidor Ejemplo: Documentación para generación automática del documento WSDL</wsdl:documentation>
+
        <wsdl:port name="CalculaPort" binding="tns:CalculaBinding">
+
            <soap-env:address location="http://localhost/servicioWeb2/index.php"/>
+
        </wsdl:port>
+
    </wsdl:service>
+
</wsdl:definitions>
+
</source>
+
{{MRM_Actividad|
+
*Realizamos un servicio web con fichero  wsdl para compartir la calculadora Racional
+
}}
+
 
+
 
+
 
+
 
+
{{MRM_Recursos de la Web|
+
*http://es.wikipedia.org/wiki/Simple_Object_Access_Protocol
+
*http://www.w3c.es/Divulgacion/GuiasBreves/ServiciosWeb
+
*http://danyalejandro.com/portafolio/articulos/web-services-php-breve-introduccion
+
*Para un listado de servicos web nusoap.sourceforge.net
+
*http://www.webservicex.net, servicios web listos para utilizar
+
*http://xmethods.net, otro clásico
+
*http://webservices.seekda.com, buscador y directorio de servicios web muy completo, aunque figuran servicios desactualizados o retirados
+
*http://www.wsindex.org/Web_Services, servicios web y recursos relacionados}}
+
*http://www.actionscript.org/forums/showthread.php3?t=70742
+

Última revisión de 22:32 13 feb 2019

Road Works.svg Trabajo en proceso, espera cambios frecuentes. Tu ayuda y retroalimentación son bienvenidos.
Ver página de charlas.
Road Works.svg



https://www.whoishostingthis.com/resources/soap/
https://velneo.es/velneo-los-web-services/
https://www.youtube.com/watch?v=KSic3tppmTc