Diferencia entre revisiones de «ManuelRomero/DAW/dwes/serviciosWebSoap»

De WikiEducator
Saltar a: navegación, buscar
(PARTE 1 DE LA PRÁCTICA SIN FICHERO WSDL)
(Generando la clase a partir del wsdl wsdl2php)
 
(3 revisiones intermedias por el mismo usuario no mostrado)
Línea 94: Línea 94:
  
 
===USANDO WSDL===
 
===USANDO WSDL===
*Pero a priori esta interfaz de los métodos (nombre, parámetros y  valor de retorno) no son conocidas por los que las quieren usar
+
*Ahora estamos en el caso de que esta interfaz de los métodos (nombre, parámetros y  valor de retorno) no son conocidas por los que las quieren usar
 
*Para ello las debemos publicar es un documento WSDL.
 
*Para ello las debemos publicar es un documento WSDL.
 
*Para generar este docuemento tenemos utilidades que automatzan (a mano es algo complicado, cuando menos tedioso ).
 
*Para generar este docuemento tenemos utilidades que automatzan (a mano es algo complicado, cuando menos tedioso ).
 
*Pasos a realizar
 
*Pasos a realizar
#Primero debemos comentar los métodos con las directivas o marcas usados por lenguejes que generan documentación como javadoc o phpdocumetor
+
#Primero debemos comentar los métodos con las directivas o marcas usados por lenguejes que generan documentación como '''''javadoc''''' o '''''phpDocumentor'''''
 
*Entre las más importantes usarmeos @param @return
 
*Entre las más importantes usarmeos @param @return
 
*Nos quedará
 
*Nos quedará
Línea 122: Línea 122:
 
         require_once 'serverW.php';
 
         require_once 'serverW.php';
 
         require_once'WSDLDocument.php'; //script que generará el fichero xml  
 
         require_once'WSDLDocument.php'; //script que generará el fichero xml  
 +
 +
        $url="Especifica la ubiación del fichero servidor con los comentarios @param..."
 +
        $uri="especifica la ubiación de los ficheros dominio de nombres"
 
          
 
          
 
        
 
        
 
         //serviciow.php es el fichero que genera el objeto servidor soap  
 
         //serviciow.php es el fichero que genera el objeto servidor soap  
         $accion = new WSDLDocument("serverW","http://localhost/Saop4/serviciow.php",  
+
         $accion = new WSDLDocument("serverW",$url,$uri);
                                            "http://localhost/Saop4");
+
 
              
 
              
 
       echo  $accion->saveXML(); //Genera el en  navegador el fichero xml que hay que revisar
 
       echo  $accion->saveXML(); //Genera el en  navegador el fichero xml que hay que revisar
Línea 134: Línea 136:
 
     3º: El espacio de nombres destino.
 
     3º: El espacio de nombres destino.
 
  * */
 
  * */
 
  
 
?>
 
?>
 
</source>
 
</source>
======
+
*Revisa la cabecera del xml por si tubieras que añadir algún nombre de dominio ns, fíjate en los ejemplos de los apuntes
 +
*Coge el contenido que sale por la pantalla del navegador y pégala en un fichero. nombralo con extensión '''''xml'''''
 +
 
 +
===Generando la clase  a partir del wsdl '''''wsdl2php'''''===
 
Ahora tenemos el xml que describe el servicio soap el fichero serviciow.wsdl.xml
 
Ahora tenemos el xml que describe el servicio soap el fichero serviciow.wsdl.xml
 
Nuestro objeto servidor deberá publicar el interfaz de los métodos que servimos
 
Nuestro objeto servidor deberá publicar el interfaz de los métodos que servimos
Línea 146: Línea 150:
  
 
   //En este caso especificmos el fichero de descripcion del servicio generado anteriormente con la herramienta '''''WSDLDocument'''''
 
   //En este caso especificmos el fichero de descripcion del servicio generado anteriormente con la herramienta '''''WSDLDocument'''''
     $server = new SoapServer("http://localhost/Saop4/serviciow.wsdl.xml");
+
     $server = new SoapServer("ubicación del fichero xml");
  
 
   $server->setClass('ServerW');
 
   $server->setClass('ServerW');
Línea 177: Línea 181:
 
  * ServerW class
 
  * ServerW class
 
  *  
 
  *  
  * Clase pepe
+
  * Clase ServerW
 
  *  
 
  *  
 
  * @author    {author}
 
  * @author    {author}
Línea 210: Línea 214:
 
       );
 
       );
 
   }
 
   }
 
+
//Así para el resto de métodos que puedo consumir por que el servidor nos ofrece.
  /**
+
  * Devuelve un array con los códigos de todas las familias
+
  *
+
  * @param 
+
  * @return UNKNOWN
+
  */
+
  public function getFamilias() {
+
    return $this->__soapCall('getFamilias', array(),      array(
+
            'uri' => 'http://localhost/Saop4',
+
            'soapaction' => ''
+
          )
+
      );
+
  }
+
  /**
+
  * Devuelve un array con los códigos de los productos de una familia
+
  *
+
  * @param string $familia
+
  * @return string
+
  */
+
  public function getProductosFamilia($familia) {
+
    return $this->__soapCall('getProductosFamilia', array($familia),      array(
+
            'uri' => 'http://localhost/Saop4',
+
            'soapaction' => ''
+
          )
+
      );
+
  }
+
  /**
+
  * Devuelve el número de unidades que existen en una tienda de un producto
+
  *
+
  * @param string $codigo
+
  * @param int $tienda
+
  * @return int
+
  */
+
  public function getStock($codigo, $tienda) {
+
    return $this->__soapCall('getStock', array($codigo, $tienda),      array(
+
            'uri' => 'http://localhost/Saop4',
+
            'soapaction' => ''
+
          )
+
      );
+
  }
+
}
+
  
 
?>
 
?>
Línea 257: Línea 220:
 
</source>
 
</source>
 
*Tenemos las clases que el servidor nos ofrece y podemos usar facilmente
 
*Tenemos las clases que el servidor nos ofrece y podemos usar facilmente
 +
 
===Usando las clases del servicio===
 
===Usando las clases del servicio===
  

Última revisión de 01:05 13 mar 2014

Práctica de servicos web con SOAP

  • A partir de la descripción de la práctica.
  • Tenemos una serie de métodos o funciones que queremos ofrecer a otras aplicacones web.

Fichero del servicio web

  • server.php: en él temenos los métodos que qeremos ofrecer.
  • La clase DB.PHP contiene la parte del modelo de datos (conexión a bd, y métodos para recuperar información concreta.
  • La clase producto.php tiene los atributos del producto y sus métodos get and set.
<?php
require_once('DB.php');
require_once('producto.php');
 
class Server {
    /**
     * Obtiene el PVP de un producto a partir de su código
     * 
     */
    public function getPVP($codigo){
      $producto = DB::obtieneProducto($codigo);
      return $producto->getPVP();
    }
    /**
     * Devuelve un array con los códigos de todas las familias
     * 
     */
    public function getFamilias(){
      $familias = DB::obtieneFamilias();
      return $familias;
    }
    /**
     * Devuelve un array con los códigos de los productos de una familia
     * 
     */
    public function getProductosFamilia($familia){
      $productos = DB::obtieneProductosFamilia($familia);
      return $productos;
    }
 
    /**
     * Devuelve el número de unidades que existen en una tienda de un producto
     * 
     */
    public function getStock($codigo, $tienda){
        $unidades = DB::obtieneStock($codigo, $tienda);
        return $unidades;
    }
}
 
?>
  • Lo que queremos es ofrecer estos métodos para que otras aplicaciones las usen
  • Si tenemos la situación que conocemos perfectamente estos métodos, no necesitaremos ningún fichero wsdl que los describa, sino que directamente los podemos usar.
  • La prctica tiene dos partes, una sin usar el fichero wsdl y otra usándolo.

PARTE 1 DE LA PRÁCTICA SIN FICHERO WSDL

  • Crearemos un objeto de la case SoapServer para que haya un obejto en el servidor esperadno a que haya una solicitud del cliente y atenderla
  • Para ello crearemos el fichero servicio.php
<?php
require_once('server.php');
 
//Sin WSDL -> uri es obligatorio
 $server = new SoapServer(null, array('uri'=>"aquí poner el directorio donde tengamos el servicio"));
 
 $server->setClass('Server');
 $server->handle();
?>
  • Observa que creamos un objeto del tipo SoaoServer
  • Cargamos en ese objeto la clase que contine los métodos del servicio
  • con handle generamos la respuesta del fichero html.

Usar el servicio

  • Ahora ya tenemos el servicio y el objeto que esta escuchando esperando que alguien quiera usarlo
  • implementamos el fichero cliente
  • En él instanciamos un objeto de la clase SoapClient como se ve en el fichero descrito a continuación
<?php
$url="especificar la ubicación absoluta del fichero que contiene el objeto SoapServer";
$uri="especificar el directorio donde está el fichero"
 
//Creamos un cliente para llamar a esa URL. 
//Es obligatorio establecer el parámetro 'uri' al no tener WSDL , igual que ocurría al instanciar el objeto SoapServer
 
$cliente = new SoapClient(null, array('location'=>$url,'uri'=>$uri"http://localhost/Saop"));
 
//Ahora por ejemplo podemos consumir el servicio getFamilias();
$familias = $cliente->getFamilias();
print_r($familias);
 
//Prueba el resto de servicios.
 
?>

USANDO WSDL

  • Ahora estamos en el caso de que esta interfaz de los métodos (nombre, parámetros y valor de retorno) no son conocidas por los que las quieren usar
  • Para ello las debemos publicar es un documento WSDL.
  • Para generar este docuemento tenemos utilidades que automatzan (a mano es algo complicado, cuando menos tedioso ).
  • Pasos a realizar
  1. Primero debemos comentar los métodos con las directivas o marcas usados por lenguejes que generan documentación como javadoc o phpDocumentor
  • Entre las más importantes usarmeos @param @return
  • Nos quedará
  /**
     * Obtiene el PVP de un producto a partir de su código
     * @param string $cod@igo
     * @return float
     * 
     * 
     */
    public function getPVP($codigo){
      $producto = DB::obtieneProducto($codigo);
      return $producto->getPVP();
...
  • Entre los tipos usaremos int para entero string para caracter string[] para un array o registro
  • Una vez hecho esto procedemos a generar un fichero php para que usando [WSDLDocument|http://code.google.com/p/wsdldocument/] se nos genere el fichero correspondiente
  • como indican en los apuntes escribimos el fichero genera.php
<?php
//serverW.php es el fichero descrito anteriormente, donde se implementan los métodos que se se ofrecen
        require_once 'serverW.php';
        require_once'WSDLDocument.php'; //script que generará el fichero xml 
 
        $url="Especifica la ubiación del fichero servidor con los comentarios @param..."
        $uri="especifica la ubiación de los ficheros dominio de nombres"
 
 
         //serviciow.php es el fichero que genera el objeto servidor soap 
        $accion = new WSDLDocument("serverW",$url,$uri);
 
      echo  $accion->saveXML(); //Genera el en  navegador el fichero xml que hay que revisar
/* LOS PARAMETROS DE WSDLDOCUMENT(   )
    1º: El nombre de la clase que gestionará las peticiones al servicio.
    2º: La URL en que se ofrece el servicio.
    3º: El espacio de nombres destino.
 * */
 
?>
  • Revisa la cabecera del xml por si tubieras que añadir algún nombre de dominio ns, fíjate en los ejemplos de los apuntes
  • Coge el contenido que sale por la pantalla del navegador y pégala en un fichero. nombralo con extensión xml

Generando la clase a partir del wsdl wsdl2php

Ahora tenemos el xml que describe el servicio soap el fichero serviciow.wsdl.xml Nuestro objeto servidor deberá publicar el interfaz de los métodos que servimos

<?php
  require_once('serverW.php');
 
  //En este caso especificmos el fichero de descripcion del servicio generado anteriormente con la herramienta '''''WSDLDocument'''''
    $server = new SoapServer("ubicación del fichero xml");
 
  $server->setClass('ServerW');
  $server->handle();
?>
  • Ahora instalamos la herramienta wsdl2php para generar un fichero php en la máquina cliente que contiene los métodos del servidor que podemos usar según las especificaciones del fichero wsdl
  • Descargamos
http://sourceforge.net/projects/wsdl2php/
  • Instalamos
 sudo pear install wsdl2php-0.2.1-pear.tgz
  • ahora generamos la clase a partir de la especificación wsdl y podemos usar en el cliente
wsdl2php serviciow.wsdl.xml

y generamos un fichero. Si observamos al final del fichero wsdl

    <wsdl:service name="ServerW">
        <wsdl:documentation>Clase ServerW</wsdl:documentation>
        <wsdl:port name="ServerWPort" binding="tns:ServerWBinding">
            <soap-env:address location="http://localhost/Saop4/serviciow.php"/>
        </wsdl:port>
    </wsdl:service>
  • El nombre del fichero que genera es ServerW.php
  • Si analizamos este fichero
<?php
/**
 * ServerW class
 * 
 * Clase ServerW
 * 
 * @author    {author}
 * @copyright {copyright}
 * @package   {package}
 */
class ServerW extends SoapClient {
 
  private static $classmap = array(
                                   );
 
  public function ServerW($wsdl = "serviciow.wsdl.xml", $options = array()) {
    foreach(self::$classmap as $key => $value) {
      if(!isset($options['classmap'][$key])) {
        $options['classmap'][$key] = $value;
      }
    }
    parent::__construct($wsdl, $options);
  }
 
  /**
   * Obtiene el PVP de un producto a partir de su código 
   *
   * @param string $codigo
   * @return float
   */
  public function getPVP($codigo) {
    return $this->__soapCall('getPVP', array($codigo),       array(
            'uri' => 'http://localhost/Saop4',
            'soapaction' => ''
           )
      );
  }
//Así para el resto de métodos que puedo consumir por que el servidor nos ofrece.
 
?>
  • Tenemos las clases que el servidor nos ofrece y podemos usar facilmente

Usando las clases del servicio

  • Ahora usamos la clase generada anteriormente
  • Esta clase que extiende SoapCliente
  • En ella tenemos los métodos que el servidor ofrece como un servicio
  • Lo ejecutamos y verificamos su funcionamiento.
<?php
 require_once 'ServerW.php';
 
 
//Instanciamos un objeto de la case ServerW
 //Esta clase se ha generado automáticamente por la herramienta wsdl2php
$cliente = new ServerW();
 
// Probamos a obtener el array con todas las familias
$familias = $cliente->getFamilias();
print_r($familias);
print "<br />";
 
// Probamos a obtener todos los productos de una familia
$productos = $cliente->getProductosFamilia("ORDENA");
print_r($productos);
print "<br />";
 
// Probamos a obtener el precio de un producto
$pvp = $cliente->getPVP("KSTMSDHC8GB");
print("El PVP es ".$pvp);
print "<br />";
 
// Probamos a obtener el stock de un producto en una tienda
$unidades = $cliente->getStock("KSTMSDHC8GB", 3);
print("Existen ".$unidades." unidades");
?>