Ultima revisión 22/06/2013
Zend Framework: Web Service SOAP con atributos en la respuesta
Bueno como no podía ser de otra manera, hoy voy a hacer otro artículo sobre Zend Framwork en dónde explicaré cómo asignar atributos en las etiquetas de la respuesta de un mensaje SOAP. Para ello nos ayudaremos del IDE NetBeans 7.2.1 que comentamos en el artículo anterior Cómo instalar Zend Framework en Windows y Netbeans 7.2.1 y que paso a repetir para evitar leer información no nocesaria.
Bueno lo primero que debemos hacer es crear un proyecto nuevo en NetBeans. Para ello, agregamos un nuevo proyecto pulsando en el botón de New Project, seleccionamos en PHP Application y pulsamos en Next.
En la pantalla que nos sale escribimos un Nombre de Proyecto en el campo Project Name y el directorio dónde queremos que se cree el proyecto en el campo Source Folder y le damos a Next hasta que nos pida qué Framework escoger.
Entonces pinchamos en Zend y después el en enlace que aparece que pone options...
Ya podemos decir que todo está OK por lo que pulsamos en Finish para crear el proyecto nuevo.
Ahora nos vamos al navegador y escribimos la ruta del proyecto para comprobar que todo está correcto. En nuestro ejemplo es http://localhost/ZendProject1/public
Si obtenemos un error Server 500 lo que debemos hacer es corregir el archivo .htaccess
Si el error que nos sale es como:
Warning: require_once(Zend/Application.php) [function.require-once]: failed to open stream: No such file or directory in D:\httpdocs\zfp1\public\index.php on line 18
Fatal error: require_once() [function.require]: Failed opening required 'Zend/Application.php' (include_path='D:\httpdocs\zfp1\library;.;c:\php\includes;C:\AppServ\httpdocs\library') in D:\httpdocs\zfp1\public\index.php on line 18
lo que debemos hacer es cambiar el código del public/index.php:
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
Por este otro:
// Ensure library/ is on include_path
$siteRootDir = dirname($_SERVER['DOCUMENT_ROOT']).'\\httpdocs\\';
set_include_path(
$siteRootDir . '/library' . PATH_SEPARATOR
. $siteRootDir . '/application' . PATH_SEPARATOR
. get_include_path()
);
Creación de los ficheros necesarios
Primero creamos el archivo servicio_schedule.php con el siguiente contenido:
<?php
/**
* @author Pablo Fernández Casado
*
* 21/06/2013
* http://www.islavisual.com
*
* Archivo para definir el servicio de un Web Service creado con Zend Framework
*/
class Events {
/**
* @var string
*/
public $event;
}
class Meeting {
/** @var Events[] */
public $meeting;
}
//*************************************
class Schedule {
/**
* @property string
* @return Meeting
*/
public function setMeeting() {
$schedulle = new Meeting();
$event = new Events();
$event->event = new SoapVar('<event id="1" where="Príncipe de Vergara 10" time="'.date("d-m-Y H:i:s").'">Zend Conference</event>', XSD_ANYXML);
$schedulle->meeting[] = $event;
return $schedulle;
}
}
?>
Ahora creamos el archivo servicio_SOA.php con el siguiente contenido:
<?php
/**
* @author Pablo Fernández Casado
*
* 21/06/2013
* http://www.islavisual.com
*
* Archivo que genera de forma automática un WSDL a partir de la clase Schedule
* utilizando Zend Framework
*/
// Se debe agregar al path el directorio raíz que contiene al framework
defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
$siteRootDir = dirname($_SERVER['DOCUMENT_ROOT']).'\\httpdocs\\';
set_include_path($siteRootDir . '/library' . PATH_SEPARATOR . $siteRootDir . '/application' . PATH_SEPARATOR . get_include_path());
// Se incluye la clase a generar
require_once('servicio_schedule.php');
// Si en la url está presente la entrada ?wsdl
if (strtolower($_SERVER['QUERY_STRING']) == "wsdl") {
// Se incluye la clase AutoDiscover que es la encargada de generar en forma automática el WSDL
require_once('Zend/Soap/AutoDiscover.php');
require_once('Zend/Soap/Wsdl/Strategy/ArrayOfTypeComplex.php');
$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setComplexTypeStrategy(new Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex());
$autodiscover->setOperationBodyStyle(
array('use' => 'literal',
'namespace' => 'http://framework.zend.com')
);
$autodiscover->setClass('Schedule');
$autodiscover->handle();
}
// Si no
else {
require_once('Zend/Soap/Server.php');
$wsdl_url = sprintf('http://%s%s?wsdl', $_SERVER['HTTP_HOST'], $_SERVER['SCRIPT_NAME']);
$server = new Zend_Soap_Server($wsdl_url);
$server->setClass('Schedule');
$server->handle();
}
?>
Simulación del Web Service con SoapUI
SoapUI es una aplicación muy versátil que nos permite probar, simular y generar código de servicios web de forma ágil, partiendo del contrato de los mismos en formato WSDL y con vínculo SOAP sobre HTTP. Es gratuita para uso no comercial y, para temas de desarrollo, nos permitirá realiar pruebas de forma sencilla.
Podemos descargarla de SoapUI.org
Una vez descargada e instalada, abrimos la aplicación y dónde pone Project, arriba a la izquierda, pinchamos el botón derecho del ratón y le damos a New soapUI Project.
Entonces nos saldrá una pantalla parecida a la que muestro e introducimos el nombre del proyecto y la URL del WSDL y, pulsamos OK.
Si ahora desplegamos todas las opciones que nos salen a la izquierda y pulsamos con el botón derecho del ratón en Request 1 nos creará un mensaje de petición similar a:
Que en modo texto es:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fram="http://framework.zend.com">
<soapenv:Header/>
<soapenv:Body>
<fram:setMeeting/>
</soapenv:Body>
</soapenv:Envelope>
Y si ahora le damos al botón verde de la ventana Request 1, que es para enviar la petición al servidor, el resultado es:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://framework.zend.com" xmlns:ns2="http://localhost/zfp1/public/servicio_SOA.php">
<SOAP-ENV:Body>
<ns1:setMeetingResponse>
<return>
<meeting>
<ns2:Events>
<event id="1" where="Príncipe de Vergara 10" time="22-06-2013 17:43:57">Zend Conference</event>
</ns2:Events>
</meeting>
</return>
</ns1:setMeetingResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Por lo que ya tenemos la respuesta y un mensaje con attributos en la etiqueta. En el próximo artículo mostraremos cómo leer estos atributos cuando nos los envían a nosotros y tenemos que procesarlos.