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

De WikiEducator
Saltar a: navegación, buscar
(USANDO WSDL)
(==)
Línea 139: Línea 139:
 
</source>
 
</source>
  
======
+
===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

Revisión de 23:59 12 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 phpdocumetor
  • 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 
 
 
         //serviciow.php es el fichero que genera el objeto servidor soap 
        $accion = new WSDLDocument("serverW","http://localhost/Saop4/serviciow.php", 
                                             "http://localhost/Saop4");
 
      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.
 * */
 
 
?>

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("http://localhost/Saop4/serviciow.wsdl.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 pepe 
 * 
 * @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' => ''
           )
      );
  }
 
  /**
   * 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' => ''
           )
      );
  }
}
 
?>
  • 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");
?>