Estamos escribiendo una aplicación cliente-servidor SOAP en PHP. Dominar las pruebas de API SOAP

Parte lírica.

Imagine que ha implementado o está implementando un determinado sistema al que debería ser accesible desde el exterior. Aquellos. hay un determinado servidor con el que necesita comunicarse. Por ejemplo un servidor web.

Este servidor puede realizar muchas acciones, trabajar con la base de datos, realizar algunas solicitudes de terceros a otros servidores, hacer algunos cálculos, etc. vivir y posiblemente desarrollarse según el escenario que conoce (es decir, según el escenario de los desarrolladores). No es interesante para una persona comunicarse con un servidor de este tipo, porque es posible que no pueda o no quiera proporcionar páginas hermosas con imágenes y otros contenidos fáciles de usar. Está escrito y funciona para funcionar y proporcionar datos cuando se le solicita, sin preocuparse de que sea legible por humanos, el cliente se encargará de ello él mismo.

Otros sistemas, al acceder a este servidor, ya pueden disponer de los datos recibidos de este servidor a su propia discreción: procesarlos, acumularlos, emitirlos a sus clientes, etc.

Bueno, una de las opciones para comunicarse con dichos servidores es SOAP. Protocolo de intercambio de mensajes SOAP xml.

Parte práctica.

Un servicio web (así se llama lo que proporciona el servidor y lo que utilizan los clientes) permite comunicarse con el servidor con mensajes claramente estructurados. El caso es que el servicio web no acepta ningún dato. El servicio web responderá con un error ante cualquier mensaje que no cumpla las normas. El error, por cierto, también estará en formato xml con una estructura clara (lo que no ocurre con el texto del mensaje).

WSDL (lenguaje de descripción de servicios web). Las reglas mediante las cuales se componen los mensajes para el servicio web también se describen mediante xml y también tienen una estructura clara. Aquellos. Si un servicio web ofrece la posibilidad de llamar a un método, debe permitir a los clientes saber qué parámetros se utilizan para este método. Si el servicio web espera una cadena para el Método1 como parámetro y la cadena debe denominarse Param1, entonces estas reglas se especificarán en la descripción del servicio web.

Como parámetros se pueden pasar no sólo tipos simples, sino también objetos y colecciones de objetos. La descripción de un objeto se reduce a una descripción de cada componente del objeto. Si un objeto consta de varios campos, se describe cada campo, su tipo, nombre (cuáles son los valores posibles). Los campos también pueden ser de tipo complejo, y así sucesivamente hasta que la descripción de los tipos termine con campos simples: cadena, booleano, número, fecha... Sin embargo, algunos tipos específicos pueden resultar simples, es importante que los clientes puede entender qué valores pueden contener.

Para los clientes basta con conocer la URL del servicio web, siempre estará cerca el wsdl, del cual se pueden hacer una idea de los métodos y sus parámetros que proporciona este servicio web.

¿Cuáles son las ventajas de todas estas campanas y silbatos?

  • En la mayoría de los sistemas, la descripción de métodos y tipos se produce automáticamente. Aquellos. el programador en el servidor solo necesita decir que este método se puede llamar a través de un servicio web y la descripción wsdl se generará automáticamente.
  • La descripción, que tiene una estructura clara, es legible por cualquier cliente de jabón. Aquellos. cualquiera que sea el servicio web, el cliente entenderá qué datos recibe el servicio web. Usando esta descripción, el cliente puede construir su propia estructura interna de clases de objetos, la llamada. vinculante" y. Como resultado, el programador que utiliza el servicio web tiene que escribir algo como (pseudocódigo):

    NuevoUsuario:=TSoapUser.Create("Vasya","Pupkin","admin"); jabón.AddUser(NuevoUsuario);

  • Validación automática.

    • validación xml. xml debe estar bien formado. XML no válido: inmediatamente un error para el cliente, déjelo solucionarlo.
    • validación de esquema. xml debe tener una estructura determinada. xml no coincide con el esquema; inmediatamente aparece un error para el cliente, déjelo solucionarlo.
    • El servidor SOAP lleva a cabo la verificación de datos para que los tipos de datos y las restricciones coincidan con la descripción.
  • La autorización y la autenticación se pueden implementar mediante un método independiente. de forma nativa. o utilizando autorización http.
  • Los servicios web pueden funcionar tanto a través del protocolo SOAP como a través de http, es decir, a través de solicitudes de obtención. Es decir, si los parámetros son datos simples (sin estructura), simplemente puede llamar al get www.site.com/users.asmx/GetUser?Name=Vasia o publicarlo de forma habitual. Sin embargo, esto no ocurre en todas partes ni siempre.
  • ... ver en Wikipedia

También hay muchas desventajas:

  • Tamaño de mensaje excesivamente grande. Bueno, aquí la naturaleza misma de xml es tal que el formato es redundante, cuantas más etiquetas, más información inútil. Además, el jabón añade su redundancia. Para los sistemas de intranet, el problema del tráfico es menos grave que para Internet, por lo que el jabón para redes locales tiene más demanda; en particular, Sharepoint tiene un servicio de jabón web con el que puede comunicarse con éxito (con algunas limitaciones).
  • Cambiar automáticamente la descripción de un servicio web puede dañar a todos los clientes. Bueno, es así para cualquier sistema, si no se admite la compatibilidad con métodos antiguos, todo se caerá...
  • No es un inconveniente, sino un inconveniente. Todas las llamadas a métodos deben ser atómicas. Por ejemplo, cuando trabajamos con una base de datos, podemos iniciar una transacción, ejecutar varias consultas y luego revertir o confirmar. No hay transacciones en jabón. Una petición, una respuesta, la conversación ha terminado.
  • Lidiar con la descripción de lo que hay en el lado del servidor (¿está todo descrito correctamente?) y lo que hay en el cliente (¿qué me describieron aquí?) puede ser bastante difícil. Hubo varias ocasiones en las que tuve que lidiar con el lado del cliente y convencer al programador del servidor de que sus datos estaban descritos incorrectamente, pero él no podía entender nada al respecto, porque la generación automática y no debería hacerlo, es una cuestión de software. Y el error, naturalmente, estaba en el código del método; el programador simplemente no lo vio.
  • La práctica demuestra que los desarrolladores de servicios web están terriblemente lejos de las personas que utilizan estos servicios web. En respuesta a cualquier solicitud (válida desde el exterior), puede aparecer un error incomprensible "Error 5. Todo está mal". Todo depende de la conciencia de los desarrolladores :)
  • Seguro que todavía no recuerdo algo...

Como ejemplo, existe un servicio web abierto belavia:

  • http://86.57.245.235/TimeTable/Service.asmx: punto de entrada, también hay una descripción textual de los métodos para desarrolladores externos.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL: descripción wsdl de métodos y tipos de datos recibidos y devueltos.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList: descripción de un método específico con un ejemplo del tipo de solicitud xml y respuesta xml.

Puede crear y enviar manualmente una solicitud como:

POST /TimeTable/Service.asmx HTTP/1.1 Host: 86.57.245.235 Tipo de contenido: texto/xml; charset=utf-8 Longitud del contenido: longitud SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

la respuesta vendrá:

HTTP/1.1 200 OK Fecha: lunes, 30 de septiembre de 2013 00:06:44 GMT Servidor: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 4.0.30319 Control de caché: privado, máximo -age=0 Tipo de contenido: texto/xml; charset=utf-8 Contenido-Longitud: 2940

PD: Anteriormente, se abrió el servicio web de Aeroflot, pero después de que 1C agregó soporte para SOAP a 8ku, un grupo de probadores beta de 1C lo instalaron con éxito. Ahora algo ha cambiado allí (no sé la dirección, puedes buscarla si estás interesado).
Descargo de responsabilidad de ZZY. Habló en el nivel cotidiano. Puedes patear.

JABÓN-un protocolo de texto que utiliza XML para intercambiar mensajes estructurados en un entorno informático distribuido. Originalmente, SOAP estaba destinado principalmente a implementar llamadas a procedimientos remotos (RPC), y el nombre era un acrónimo: Protocolo simple de acceso a objetos. El protocolo se utiliza ahora para intercambiar mensajes arbitrarios en formato XML, y no sólo para llamar a procedimientos. La especificación oficial de la última versión 1.2 del protocolo no descifra el nombre SOAP de ninguna manera. SOAP es una extensión del protocolo XML-RPC. SOAP se puede utilizar con cualquier protocolo de capa de aplicación: SMTP, FTP, HTTP, etc. Sin embargo, su interacción con cada uno de estos protocolos tiene sus propias características que deben definirse por separado. La mayoría de las veces, SOAP se utiliza sobre HTTP. SOAP es uno de los estándares en los que se basan las tecnologías de servicios web. La comunicación entre los servicios web y sus clientes se realiza a través de mensajes en formato XML. SOAP (Protocolo simple de acceso a objetos) es un protocolo de mensajes para seleccionar servicios web. Podemos decir que el formato SOAP es ideal para la tecnología RPC (Llamada a Procedimiento Remoto), ya que el mensaje SOAP contiene parámetros enviados por el cliente o un valor de retorno enviado por el servicio.

Ventajas de utilizar el formato SOAP:

· Tipos de datos más flexibles.

· Soporte para encabezados y extensiones:

Defectos:

· El uso de SOAP para transmitir mensajes aumenta su volumen y reduce la velocidad de procesamiento. En sistemas donde la velocidad es importante, es más común enviar documentos XML a través de HTTP directamente, donde los parámetros de solicitud se pasan como parámetros HTTP normales.

· Aunque SOAP es un estándar, diferentes programas suelen generar mensajes en un formato incompatible. Por ejemplo, el servidor WebLogic no entenderá una solicitud generada por un cliente AXIS.

Conceptos básicos del protocolo: La parte que envía el mensaje SOAP se denomina remitente SOAP y la parte que lo recibe se denomina receptor SOAP. La ruta que sigue un mensaje SOAP desde el remitente original hasta el destinatario final se denomina ruta del mensaje. La ruta del mensaje contiene el remitente original, el destinatario final y 0 o más intermediarios SOAP. Los objetos que procesan mensajes según las reglas de protocolos SOAP específicos se denominan nodos SOAP. La unidad elemental de información que participa en el intercambio entre nodos SOAP se denomina mensaje SOAP; es un documento XML con un elemento raíz contenedor SOAP.

  • Tutorial

¡Hola a todos!
Dio la casualidad de que recientemente comencé a desarrollar servicios web. Pero hoy el tema no es sobre mí, sino sobre cómo podemos escribir nuestro propio servicio web XML basado en el protocolo SOAP 1.2.

Espero que después de leer el tema puedas:

  • escribir su propia implementación de servidor de una aplicación web;
  • escribir su propia implementación cliente de una aplicación web;
  • escriba su propia descripción del servicio web (WSDL);
  • enviar las matrices del cliente del mismo tipo de datos al servidor.
Como habrás adivinado, toda la magia se hará usando PHP y las clases integradas SoapClient y SoapServer. Nuestro conejo será un servicio de envío de mensajes SMS.

1 planteamiento del problema

1.1 Límites

Al principio propongo abordar el resultado que lograremos al final del tema. Como se anunció anteriormente, escribiremos un servicio para enviar mensajes SMS y, más precisamente, recibiremos mensajes de diferentes fuentes a través del protocolo SOAP. Después de eso, consideraremos en qué forma llegan al servidor. Desafortunadamente, el proceso de poner en cola los mensajes para su posterior envío al proveedor está más allá del alcance de esta publicación por muchas razones.

1.2 ¿Qué datos cambiaremos?

¡Genial, hemos decidido los límites! El siguiente paso que hay que dar es decidir qué datos intercambiaremos entre el servidor y el cliente. Sobre este tema, le sugiero no dividirse por mucho tiempo y responder de inmediato las preguntas principales usted mismo:
  • ¿Qué datos mínimos se deben enviar al servidor para poder enviar un mensaje SMS a un suscriptor?
  • ¿Qué datos mínimos se deben enviar desde el servidor para satisfacer las necesidades del cliente?
Algo me dice que para esto necesitas enviar lo siguiente:
  • número de teléfono móvil y
  • texto del mensaje SMS.
En principio, estas dos características son suficientes para enviar, pero inmediatamente me imagino el caso de que te llegue un SMS con felicitaciones de cumpleaños a las 3 de la mañana, ¡o a las 4! ¡En este momento estaré muy agradecido con todos por no olvidarse de mí! Por lo tanto, también enviaremos al servidor y
  • fecha de envío del mensaje SMS.
Lo siguiente que me gustaría enviar al servidor es:
  • Tipo de mensaje.
Este parámetro no es obligatorio, pero nos puede resultar muy útil si necesitamos decirle rápidamente al jefe cuántos de nuestros clientes hemos “encantado” con nuestra noticia, y además sacar algunas bonitas estadísticas al respecto.

¡Y sin embargo, olvidé algo! Si reflexionamos un poco más, cabe destacar que el cliente puede enviar al servidor un mensaje SMS o varios a la vez. En otras palabras, un paquete de datos puede contener desde uno hasta infinitos mensajes.

Como resultado, obtenemos que para enviar un mensaje SMS necesitamos los siguientes datos:

  • número de teléfono móvil,
  • texto de mensaje SMS,
  • momento de envío del mensaje SMS al suscriptor,
  • tipo de mensaje.

Hemos respondido la primera pregunta, ahora necesitamos responder la segunda pregunta. Y tal vez me permitiré perder el tiempo un poco. Por tanto, desde el servidor enviaremos únicamente datos booleanos, cuyo significado tiene el siguiente significado:

  • VERDADERO: el paquete llegó exitosamente al servidor, pasó la autenticación y se puso en cola para enviarlo al proveedor de SMS.
  • FALSO – en todos los demás casos

¡Con esto concluye la descripción del planteamiento del problema! Y finalmente, vayamos a la parte divertida: ¡descubramos qué clase de bestia extraña es este SOAP!

2 ¿Qué es el jabón?

En general, inicialmente no planeé escribir nada sobre qué es SOAP y quería limitarme a enlaces al sitio web w3.org con las especificaciones necesarias, así como enlaces a Wikipedia. Pero al final decidí escribir una breve nota sobre este protocolo.

Y comenzaré mi historia con el hecho de que este protocolo de intercambio de datos pertenece a un subconjunto de protocolos basados ​​​​en el llamado paradigma RPC (Llamada a procedimiento remoto), cuya antípoda es REST (Transferencia de estado representacional). Puede leer más sobre esto en Wikipedia; los enlaces a los artículos se encuentran al final del tema. De estos artículos debemos entender lo siguiente: “El enfoque RPC permite el uso de una pequeña cantidad de recursos de red con una gran cantidad de métodos y un protocolo complejo. Con el enfoque REST, la cantidad de métodos y la complejidad del protocolo están estrictamente limitadas, lo que significa que la cantidad de recursos individuales puede ser grande”. Es decir, en relación con nosotros, esto significa que en el caso del enfoque RPC en el sitio siempre habrá una entrada (enlace) al servicio y qué procedimiento llamar para procesar los datos entrantes que transferimos junto con los datos, mientras con el enfoque REST en nuestro El sitio tiene muchas entradas (enlaces), cada una de las cuales acepta y procesa solo ciertos datos. Si alguien que lea sabe cómo explicar la diferencia entre estos enfoques de manera aún más simple, ¡asegúrese de escribir en los comentarios!

Lo siguiente que debemos saber sobre SOAP es que este protocolo utiliza el mismo XML como transporte, lo cual por un lado es muy bueno, porque Nuestro arsenal incluye inmediatamente todo el poder de una pila de tecnologías basadas en este lenguaje de marcado, a saber, XML-Schema, un lenguaje para describir la estructura de un documento XML (¡gracias Wikipedia!), que permite la validación automática de los datos recibidos por el servidor desde clientela.

¡Y ahora sabemos que SOAP es un protocolo utilizado para implementar llamadas a procedimientos remotos y utiliza XML como transporte! Si lee el artículo en Wikipedia, también podrá aprender desde allí que se puede usar en cualquier protocolo a nivel de aplicación, y no solo en combinación con HTTP (desafortunadamente, en este tema solo consideraremos SOAP sobre HTTP). ¿Y sabes qué es lo que más me gusta de todo esto? Si no hay conjeturas, te daré una pista: ¡JABÓN!... ¿Todavía no hay conjeturas?... ¿Estás seguro de que leíste el artículo en Wikipedia?... En general, no te torturaré más. Por lo tanto, iré directamente a la respuesta: "SOAP (del protocolo simple de acceso a objetos en inglés - simple protocolo acceso a objetos; hasta la especificación 1.2)". ¡Lo más destacable de esta línea está en cursiva! No sé qué conclusiones sacó de todo esto, pero veo lo siguiente: dado que este protocolo no puede llamarse "simple" de ninguna manera (y aparentemente incluso w3 está de acuerdo con esto), desde la versión 1.2 dejó de descifrarse de alguna manera ! Y pasó a ser conocido como SOAP, simplemente SOAP, punto.

Bueno, está bien, discúlpenme, me desvié un poco. Como escribí anteriormente, XML se utiliza como transporte y los paquetes que viajan entre el cliente y el servidor se denominan sobres SOAP. Si consideras la estructura general del sobre, te resultará muy familiar, porque... Se asemeja a la estructura de una página HTML. Tiene una sección principal - Envolver, que incluye secciones Encabezamiento Y Cuerpo, o Falla. EN Cuerpo se transmiten datos y es una sección obligatoria del sobre, mientras que Encabezamiento es opcional. EN Encabezamiento Se podrá transmitir autorización o cualquier otro dato que no esté directamente relacionado con los datos de entrada de los procedimientos del servicio web. Acerca de Falla no hay nada especial que decir, excepto que llega al cliente desde el servidor en caso de algún error.

Aquí termina mi historia de revisión sobre el protocolo SOAP (veremos los sobres en sí y su estructura con más detalle cuando nuestro cliente y servidor finalmente aprendan a ejecutarlos entre sí) y comienza una nueva: sobre el compañero SOAP llamado WSDL(Lenguaje de descripción de servicios web). Sí, sí, esto es precisamente lo que nos asusta a la mayoría de nosotros incluso de intentar implementar nuestra API en este protocolo. Como resultado, normalmente reinventamos nuestra rueda con JSON como transporte. Entonces, ¿qué es WSDL? WSDL es un lenguaje para describir servicios web y acceder a ellos, basado en el lenguaje XML (c) Wikipedia. Si esta definición no le aclara todo el significado sagrado de esta tecnología, ¡intentaré describirlo con mis propias palabras!

WSDL está diseñado para permitir a nuestros clientes comunicarse normalmente con el servidor. Para ello, el archivo con extensión “*.wsdl” describe la siguiente información:

  • ¿Qué espacios de nombres se utilizaron?
  • ¿Qué esquemas de datos se utilizaron?
  • ¿Qué tipos de mensajes espera el servicio web de los clientes?
  • Qué datos pertenecen a qué procedimientos de servicios web,
  • ¿Qué trámites contiene el servicio web?
  • ¿Cómo debe el cliente llamar a los procedimientos del servicio web?
  • ¿A qué dirección se deben enviar las llamadas de los clientes?
Como puede ver, este archivo es el servicio web completo. Al especificar la dirección del archivo WSDL en el cliente, ¡sabremos todo sobre cualquier servicio web! Como resultado, no necesitamos saber absolutamente nada sobre dónde se encuentra el servicio web. ¡Todo lo que necesitas saber es la ubicación de su archivo WSDL! Pronto descubriremos que SOAP no da tanto miedo como dicen los proverbios rusos.

3 Introducción al esquema XML

Ahora sabemos mucho sobre qué es SOAP, qué contiene y tenemos una descripción general de la pila de tecnología que lo rodea. Dado que, en primer lugar, SOAP es un método de interacción entre un cliente y un servidor, y el lenguaje de marcado XML se utiliza como transporte para ello, en esta sección entenderemos un poco cómo se produce la validación automática de datos utilizando esquemas XML.

La tarea principal del diagrama es describir la estructura de los datos que vamos a procesar. Todos los datos en esquemas XML se dividen en simple(escalar) y complejo(estructuras) tipos. Los tipos simples incluyen los siguientes tipos:

  • línea,
  • número,
  • valor booleano,
  • fecha.
Algo muy sencillo que no tiene extensiones en su interior. Su antípoda son los tipos complejos complejos. El ejemplo más simple de un tipo complejo que viene a la mente de todos son los objetos. Por ejemplo, un libro. El libro consta de propiedades: autor, Nombre, precio, número ISBN etc. Y estas propiedades, a su vez, pueden ser de tipos simples o complejos. Y la tarea del esquema XML es describir esto.

¡Sugiero no ir muy lejos y escribir un esquema XML para nuestro mensaje SMS! A continuación se muestra la descripción xml del mensaje SMS:

71239876543 Mensaje de prueba 2013-07-20T12:00:00 12
Nuestro diagrama de tipo complejo se verá así:


Esta entrada dice lo siguiente: Tenemos una variable " mensaje" tipo " Mensaje"y hay un tipo complejo llamado" Mensaje", que consta de un conjunto secuencial de elementos " teléfono" tipo cadena, « texto" tipo cadena, « fecha" tipo fechahora, « tipo" tipo decimal. Estos tipos son simples y ya están definidos en la descripción del esquema. ¡Felicidades! ¡Acabamos de escribir nuestro primer esquema XML!

Creo que el significado de los elementos " elemento" Y " tipo complejo"Todo te ha quedado más o menos claro, así que no nos centraremos más en ello y pasemos directamente al elemento compositor" secuencia" Cuando usamos el elemento compositor " secuencia“Les informamos que los elementos incluidos en el mismo deben ubicarse siempre en la secuencia especificada en el esquema, y ​​todos ellos son de obligado cumplimiento. ¡Pero no te desesperes! Hay dos elementos más del compositor en los esquemas XML: " elección" Y " todo" Compositor " elección" anuncia que debe haber uno de los elementos enumerados en él, y el compositor " todo» – cualquier combinación de los elementos enumerados.

Como recordarás, en el primer apartado del tema coincidimos en que en un paquete se pueden transmitir de uno a infinito mensajes SMS. Por lo tanto, propongo comprender cómo se declaran dichos datos en el esquema XML. La estructura general del paquete podría verse así:

71239876543 Mensaje de prueba 1 2013-07-20T12:00:00 12 71239876543 Mensaje de prueba N 2013-07-20T12:00:00 12
El diagrama para un tipo tan complejo se verá así:


El primer bloque contiene la conocida declaración del tipo complejo “ Mensaje" Si te diste cuenta, entonces en cada tipo simple incluido en " Mensaje", se han agregado nuevos atributos aclaratorios " minOcurre" Y " maxOcurre" Como puedes adivinar por el nombre, el primero ( minOcurre) indica que esta secuencia debe contener al menos un elemento de tipo " teléfono», « texto», « fecha" Y " tipo", mientras que el siguiente ( maxOcurre) el atributo nos declara que hay como máximo uno de esos elementos en nuestra secuencia. Como resultado, cuando escribimos nuestros propios esquemas para cualquier dato, ¡tenemos la opción más amplia sobre cómo configurarlos!

El segundo bloque del diagrama declara el elemento " lista de mensajes" tipo " Lista de mensajes" Está claro que " Lista de mensajes"es un tipo complejo que contiene al menos un elemento" mensaje", ¡pero el número máximo de dichos elementos no está limitado!

4 Escribe tu WSDL

¿Recuerdas que WSDL es nuestro servicio web? ¡Espero que lo recuerdes! Mientras lo escribimos, nuestro pequeño servicio web se ejecutará en él. Por lo tanto, sugiero no perder el tiempo.

Por lo general, para que todo nos funcione correctamente, necesitamos transferir un archivo WSDL con el tipo MIME correcto al cliente. Para hacer esto, necesita configurar su servidor web en consecuencia, es decir, establecer el tipo MIME para archivos con la extensión “*.wsdl” en la siguiente línea:

Aplicación/wsdl+xml
Pero en la práctica, normalmente envié el encabezado HTTP a través de PHP " texto/xml»:

Encabezado("Tipo de contenido: texto/xml; charset=utf-8");
¡Y todo funcionó muy bien!

Quiero advertirles de inmediato que nuestro sencillo servicio web tendrá una descripción bastante impresionante, así que no se alarmen, porque... La mayor parte del texto es obligatorio y, habiéndolo escrito una vez, ¡puedes copiarlo constantemente de un servicio web a otro!

Dado que WSDL es XML, debe escribir sobre esto directamente en la primera línea. El elemento raíz del archivo siempre debe llamarse " definiciones»:


Normalmente, WSDL consta de 4 o 5 bloques principales. El primer bloque es la definición de un servicio web o, en otras palabras, el punto de entrada.


Aquí dice que tenemos un servicio llamado " Servicio SMS" En principio, usted puede cambiar todos los nombres del archivo WSDL por el que desee, porque no juegan absolutamente ningún papel.

Luego de esto anunciamos que en nuestro servicio web " Servicio SMS"hay un punto de entrada ("puerto") llamado " PuertoServicioSms" Es a este punto de entrada al que se enviarán todas las solicitudes de los clientes al servidor. E indicar en el elemento “ DIRECCIÓN» enlace al archivo del controlador que aceptará solicitudes.

Una vez que hayamos definido el servicio web y especificado el punto de entrada, debemos vincularle los procedimientos admitidos:


Para ello, enumera qué operaciones y de qué forma se llamarán. Aquellos. para puerto " PuertoServicioSms"un enlace se define bajo el nombre" Enlace de servicio SMS", que tiene un tipo de llamada " rpc"y HTTP se utiliza como protocolo de transmisión. Por lo tanto, indicamos aquí que realizaremos una llamada RPC a través de HTTP. Después de esto describimos qué procedimientos ( operación) son compatibles con el servicio web. Apoyaremos sólo un procedimiento – “ enviarSms" ¡A través de este procedimiento nuestros maravillosos mensajes serán enviados al servidor! Una vez declarado el procedimiento, es necesario indicar en qué forma se transmitirán los datos. En este caso se indica que se utilizarán sobres SOAP estándar.

Después de eso, necesitamos vincular el procedimiento a los mensajes:


Para ello especificamos que nuestro enlace es de tipo " Tipo de puerto de servicio SMS" y en el elemento " tipo de puerto"con el nombre del mismo tipo indicamos la vinculación de procedimientos a mensajes. Y así, el mensaje entrante (del cliente al servidor) se llamará " enviarSmsSolicitud", y saliente (del servidor al cliente) " enviarSmsRespuesta" Como todos los nombres en WSDL, los nombres de los mensajes entrantes y salientes son arbitrarios.

Ahora necesitamos describir los mensajes en sí, es decir. entrantes y salientes:


Para ello añadimos los elementos " mensaje"con nombres" enviarSmsSolicitud" Y " enviarSmsRespuesta" respectivamente. En ellos indicamos que la entrada debe ser un sobre cuya estructura corresponda al tipo de datos " Pedido" Después de lo cual se devuelve un sobre del servidor que contiene el tipo de datos - " Respuesta».

Ahora tenemos que hacer un poco: ¡agregar una descripción de estos tipos a nuestro archivo WSDL! ¿Y cómo cree que describe el WSDL los datos entrantes y salientes? Creo que ya entendiste todo hace mucho tiempo y te dijiste que usar esquemas XML. ¡Y tendrás toda la razón!


¡Puedes felicitarnos! ¡Nuestro primer WSDL ha sido escrito! Y estamos un paso más cerca de lograr nuestro objetivo.
A continuación, veremos qué nos proporciona PHP para desarrollar nuestras propias aplicaciones distribuidas.

5 Nuestro primer servidor SOAP

Anteriormente escribí que para crear un servidor SOAP en PHP usaremos la clase integrada SoapServer. Para que todas las acciones posteriores se realicen de la misma manera que para mí, deberás modificar un poco tu PHP. Para ser aún más preciso, debes asegurarte de tener instalada la extensión “php-soap”. Lo mejor es leer cómo instalarlo en su servidor web en el sitio web oficial de PHP (consulte la lista de referencias).

Una vez instalado y configurado todo, necesitaremos crear un archivo en la carpeta raíz de tu hosting” smsservice.php» con el siguiente contenido:

setClass("SoapSmsGateWay"); //Inicia el servidor $server->handle();
Espero que no sea necesario explicar qué hay encima de la línea con la función “ini_set”. Porque allí se determina qué encabezados HTTP enviaremos desde el servidor al cliente y se configura el entorno. En la línea con "ini_set" desactivamos el almacenamiento en caché del archivo WSDL para que nuestros cambios surtan efecto inmediatamente en el cliente.

¡Ahora llegamos al servidor! Como puede ver, ¡todo el servidor SOAP solo ocupa tres líneas! En la primera línea, creamos una nueva instancia del objeto SoapServer y pasamos la dirección de nuestra descripción WSDL del servicio web a su constructor. Ahora sabemos que estará ubicado en la raíz del hosting en un archivo con el nombre autoexplicativo “ smsservice.wsdl.php" En la segunda línea, le indicamos al servidor SOAP qué clase se debe extraer para procesar el sobre recibido del cliente y devolver el sobre con la respuesta. Como habrás adivinado, es en esta clase donde se describirá nuestro único método. enviarSms. ¡En la tercera línea iniciamos el servidor! ¡Eso es todo, nuestro servidor está listo! ¡Con lo cual nos felicito a todos!

Ahora necesitamos crear el archivo WSDL. Para hacer esto, puedes simplemente copiar su contenido de la sección anterior, o tomarte la libertad y “plantillarlo” un poco:

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// esquemas.xmlsoap.org/wsdl/http/" nombre="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservicio.php" />
En esta etapa, deberíamos estar completamente satisfechos con el servidor resultante, porque Podemos registrar los sobres que llegan y luego analizar con calma los datos entrantes. Para que podamos recibir algo en el servidor, necesitamos un cliente. ¡Así que vamos a ello!

6 clientes SOAP en camino

En primer lugar, necesitamos crear un archivo en el que escribiremos el cliente. Como es habitual, lo crearemos en la raíz del host y lo llamaremos " cliente.php", y dentro escribiremos lo siguiente:

lista de mensajes = nueva lista de mensajes(); $req->listademensajes->mensaje = nuevo mensaje(); $req->listademensajes->mensaje->teléfono = "79871234567"; $req->messageList->message->text = "Mensaje de prueba 1"; $req->listademensajes->mensaje->fecha = "2013-07-21T15:00:00.26"; $req->listademensajes->mensaje->tipo = 15; $cliente = nuevo SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($cliente->sendSms($req));
Describamos nuestros objetos. Cuando escribimos el WSDL, describía tres entidades para el sobre entrante al servidor: Pedido, Lista de mensajes Y Mensaje. En consecuencia clases Pedido, Lista de mensajes Y Mensaje son reflejos de estas entidades en nuestro script PHP.

Una vez que hemos definido los objetos, necesitamos crear un objeto ( $requisito), que enviaremos al servidor. ¡Después vienen las dos líneas más queridas para nosotros! ¡Nuestro cliente SOAP! Lo creas o no, esto es suficiente para que nuestro servidor comience a recibir mensajes del cliente, ¡así como para que nuestro servidor los reciba y procese con éxito! En el primero de ellos creamos una instancia de la clase SoapClient y pasamos la dirección de ubicación del archivo WSDL a su constructor, y en los parámetros indicamos explícitamente que trabajaremos utilizando el protocolo SOAP versión 1.2. En la siguiente línea llamamos al método. enviarSms objeto $cliente e inmediatamente mostrar el resultado en el navegador.
¡Ejecutémoslo y veamos qué obtuvimos finalmente!

El siguiente objeto me fue devuelto desde el servidor:

Objeto (stdClass) público "estado" => booleano verdadero
Y esto es genial, porque... ¡Ahora sabemos con certeza que nuestro servidor está funcionando y no solo funciona, sino que también puede devolver algunos valores al cliente!

¡Ahora veamos el registro que mantenemos prudentemente en el lado del servidor! En su primera parte vemos los datos brutos que llegaron al servidor:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15
Este es el sobre. ¡Ahora ya sabes cómo luce! Pero es poco probable que estemos interesados ​​en verlo todo el tiempo, así que deserialicemos el objeto del archivo de registro y veamos si todo está bien:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1 " (longitud=37) public "fecha" => cadena "2013-07-21T15:00:00.26" (longitud=22) public "tipo" => cadena "15" (longitud=2)
Como puede ver, el objeto se deserializa correctamente, ¡por lo que quiero felicitarnos a todos! ¡A continuación nos espera algo más interesante! Es decir, enviaremos al cliente al servidor no solo un mensaje SMS, ¡sino un paquete completo (para ser más precisos, tres)!

7 Envío de objetos complejos

Pensemos en cómo podemos transferir una gran cantidad de mensajes al servidor en un solo paquete. ¡Probablemente la forma más sencilla sería organizar una matriz dentro del elemento messageList! Hagamos esto:

// crea un objeto para enviar al servidor $req = new Request(); $req->listademensajes = nueva Lista de mensajes(); $msg1 = nuevo mensaje(); $msg1->teléfono = "79871234567"; $msg1->text = "Mensaje de prueba 1"; $msg1->fecha = "2013-07-21T15:00:00.26"; $msj1->tipo = 15; $msg2 = nuevo mensaje(); $msg2->teléfono = "79871234567"; $msg2->text = "Mensaje de prueba 2"; $msg2->fecha = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuevo mensaje(); $msg3->teléfono = "79871234567"; $msg3->text = "Mensaje de prueba 3"; $msg3->fecha = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->listademensajes->mensaje = $msg1; $req->listademensajes->mensaje = $msg2; $req->listademensajes->mensaje = $msg3;
Nuestros registros indican que se recibió el siguiente paquete del cliente:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
¿Qué tontería dices? Y en cierto sentido tendrás razón, porque... Tan pronto como supimos que un objeto salió del cliente, llegó a nuestro servidor exactamente de la misma forma, en forma de sobre. Es cierto que los mensajes SMS no se serializaron en XML de la manera que necesitábamos: tuvieron que estar envueltos en elementos. mensaje, no en estructura. Ahora veamos en qué forma dicho objeto llega al método. enviarSms:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1" (longitud=37) public "date" => string "2013-07-21T15:00:00.26" (longitud=22) public " tipo" => cadena "15" (longitud=2) 1 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 2" (longitud= 37) pública "fecha" => cadena "2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "teléfono " => cadena "79871234567" (longitud=11) public "texto" => cadena "Mensaje de prueba 3" (longitud=37) public "fecha" => cadena "2014-08-22T16:01:10" (longitud= 19) público "tipo" => cadena "17" (longitud=2)
¿Qué nos aporta este conocimiento? Sólo que la ruta que elegimos no es correcta y no recibimos respuesta a la pregunta: "¿Cómo podemos obtener la estructura de datos correcta en el servidor?" Pero sugiero no desesperarse e intentar convertir nuestra matriz al tipo objeto:

$req->listademensajes->mensaje = (objeto)$req->lista de mensajes->mensaje;
En este caso recibiremos otro sobre:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
Entró en el método enviarSms el objeto tiene la siguiente estructura:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1" (longitud=37) public "date" => string "2013-07-21T15:00:00.26" (longitud=22) public " tipo" => cadena "15" (longitud=2) 1 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 2" (longitud= 37) pública "fecha" => cadena "2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "teléfono " => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 3" (longitud=37) public "fecha" => cadena "2014-08-22T16:01:10" (longitud= 19) público "tipo" => cadena "17" (longitud=2)
En lo que a mí respecta, “la suma no cambia al cambiar los lugares de los términos” (c). Qué FALSO, Qué estructura– ¡aún no hemos logrado nuestro objetivo! Y para lograrlo, debemos asegurarnos de que en lugar de estos nombres incomprensibles se muestre nuestro nativo. mensaje. Pero el autor aún no sabe cómo lograrlo. Por tanto, lo único que podemos hacer es deshacernos del contenedor sobrante. En otras palabras, ahora nos aseguraremos de que en lugar de mensaje convertirse FALSO! Para hacer esto, cambie el objeto de la siguiente manera:

// crea un objeto para enviar al servidor $req = new Request(); $msg1 = nuevo mensaje(); $msg1->teléfono = "79871234567"; $msg1->text = "Mensaje de prueba 1"; $msg1->fecha = "2013-07-21T15:00:00.26"; $msj1->tipo = 15; $msg2 = nuevo mensaje(); $msg2->teléfono = "79871234567"; $msg2->text = "Mensaje de prueba 2"; $msg2->fecha = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuevo mensaje(); $msg3->teléfono = "79871234567"; $msg3->text = "Mensaje de prueba 3"; $msg3->fecha = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->listademensajes = $msg1; $req->listademensajes = $msg2; $req->listademensajes = $msg3; $req->listademensajes = (objeto)$req->lista de mensajes;
¿Qué pasa si tenemos suerte y aparece el nombre correcto en el diagrama? Para ello, veamos el sobre que llegó:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
¡Sí, no ocurrió un milagro! FALSO– ¡no ganaremos! vino a enviarSms el objeto en este caso se verá así:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public " texto" => cadena "Mensaje de prueba 1" (longitud=37) public "fecha" => cadena "2013-07-21T15:00:00.26" (longitud=22) public "tipo" => cadena "15" (longitud =2) 1 => objeto(stdClass) público "teléfono" => cadena "79871234567" (longitud=11) public "texto" => cadena "Mensaje de prueba 2" (longitud=37) pública "fecha" => cadena " 2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud= 11) público "texto" => cadena "Mensaje de prueba 3" (longitud = 37) público "fecha" => cadena "2014-08-22T16:01:10" (longitud = 19) público "tipo" => cadena " 17" (largo=2)
Como dicen – ¡“Casi”! En esta nota (un poco triste), propongo resumir lentamente las cosas y sacar algunas conclusiones por nosotros mismos.

8 Conclusión

¡Finalmente llegamos aquí! Averigüemos qué puedes hacer ahora:
  • puedes escribir el archivo WSDL necesario para tu servicio web;
  • puedes escribir fácilmente tu propio cliente que pueda comunicarse con el servidor vía SOAP;
  • puedes escribir tu propio servidor que se comunique con el mundo exterior vía SOAP;
  • puedes enviar matrices del mismo tipo de objetos al servidor desde tu cliente (con algunas restricciones).
También hicimos algunos descubrimientos durante nuestra pequeña investigación:
  • la clase nativa SoapClient no serializa correctamente estructuras de datos del mismo tipo en XML;
  • al serializar una matriz a XML, se crea un elemento adicional llamado estructura;
  • al serializar un objeto a XML se crea un elemento extra llamado FALSO;
  • FALSO menos malvado que estructura debido al hecho de que el sobre es más compacto (no se agregan espacios de nombres adicionales al encabezado XML del sobre);
  • Desafortunadamente, la clase SoapServer no valida automáticamente los datos del sobre con nuestro esquema XML (quizás otros servidores tampoco lo hagan).

SOAP (Protocolo simple de acceso a objetos) Es un protocolo estandarizado para transferir mensajes entre un cliente y un servidor. Normalmente se utiliza junto con HTTP(S), pero también puede funcionar con otros protocolos de capa de aplicación (como SMTP y FTP).
Probar SOAP desde el punto de vista de las técnicas de prueba no es fundamentalmente diferente de trabajar con otras API, pero requiere una preparación preliminar (en términos de teoría de protocolos) y herramientas de prueba especiales. En este artículo, me gustaría formular una pequeña lista de verificación de conocimientos y habilidades necesarios, que será igualmente útil tanto para un evaluador de SOAP (que a menudo no tiene idea de qué agarrar después de configurar la tarea) como para un gerente que está obligados a evaluar los conocimientos de los evaluadores y desarrollar planes de formación.

Base teórica

El hecho de que SOAP sea un protocolo tiene muchas implicaciones para las pruebas: es necesario estudiar el protocolo en sí, los estándares y protocolos "primarios" en los que se basa y (según sea necesario) las extensiones existentes.

XML
XML es un lenguaje de marcado similar a HTML. Cualquier mensaje enviado/recibido vía SOAP es un documento XML en el que los datos están convenientemente estructurados y son fáciles de leer, por ejemplo:



Julia
natasha
Recordatorio
¡No olvides escribir un artículo!


Puede obtener más información sobre XML en w3schools o codenet (en ruso). Asegúrese de prestar atención a la descripción de los espacios de nombres (un método para resolver conflictos al describir elementos en XML); su uso es obligatorio en SOAP.

XSD
A la hora de trabajar, siempre es conveniente tener una descripción estandarizada de posibles documentos XML y comprobar su correcto llenado. Existe una definición de esquema XML (o XSD para abreviar) para este propósito. Las dos características principales de XSD para un probador son la descripción de tipos de datos y la imposición de restricciones sobre posibles valores. Por ejemplo, el elemento del ejemplo anterior puede hacerse opcional y limitarse a 255 caracteres usando XSD:

...







...

Extensiones de jabón
En su trabajo, también puede encontrar varias "extensiones" de SOAP, estándares como WS-*. Uno de los más habituales es WS-Security, que permite trabajar con cifrado y firmas electrónicas. A menudo, junto con él se utiliza WS-Policy, con el que puede gestionar los derechos de uso de su servicio.

Ejemplo de uso de WS-Security:


Alicia
6S3P2EWNP3lQf+9VC3emNoT57oQ=
YF6j8V/CAqi+1nRsGLRbuZhi
2008-04-28T10:02:11Z

Todas estas extensiones son estructuras bastante complejas que no se utilizan en todos los servicios SOAP; Es poco probable que su estudio detallado en la etapa inicial de dominio de las pruebas SOAP sea relevante.

Herramientas

Como ya comprenderás, SOAP es un asunto serio; para trabajar con él es necesario conocer la teoría y numerosos estándares. En la práctica, tal complejidad generaría costos laborales muy importantes (por ejemplo, habría que mirar el diagrama en un cuaderno cada vez y enviar solicitudes con curl). Por ello, se han creado herramientas para facilitar el trabajo con SOAP.

Editores XML/XSD
Un buen probador comienza a realizar pruebas en la etapa de redacción de la documentación, por lo que es conveniente utilizar editores especiales para probar circuitos. Los dos más famosos son Oxygen (multiplataforma) y Altova (solo Windows); A ambos se les paga. Se trata de programas muy potentes que los analistas utilizan activamente al describir servicios.

En mi práctica, tres características de los editores resultaron útiles: visualización XSD, generación XML basada en XSD y validación XML basada en XSD.

1. Visualización XSD necesario para una representación visual del diagrama, lo que le permite identificar rápidamente los elementos y atributos requeridos, así como las restricciones existentes. Por ejemplo, para CheckTextRequest, el elemento de texto es obligatorio y los tres atributos son opcionales (el atributo de opciones tiene un valor predeterminado de cero).

La visualización es necesaria cuando hay muchos tipos y restricciones en el diagrama. Si sólo necesita esto y no quiere pagar por editores especiales, puede considerar alternativas gratuitas (por ejemplo, JDeveloper).

2. Generación XML basada en XSDútil cuando desea ver un ejemplo válido de un mensaje. Lo uso para experimentar rápidamente con posibles finalización de mensajes y probar los matices de cómo funcionan las restricciones.

3. Después de utilizar la función del punto 2, es útil realizar Validación XML contra XSD– es decir, verifique que el mensaje sea correcto. Juntas, las características 2 y 3 le permiten detectar defectos complicados en XSD incluso cuando el servicio en sí está en desarrollo.

Herramienta de prueba: SoapUI

Las pruebas SOAP casi siempre implican el uso de SoapUI. Puede leer sobre el uso de esta herramienta en varias fuentes (,), pero será más eficaz leer la documentación oficial. Identifico 8 niveles condicionales de competencia en SoapUI:

Nivel 1: puedo enviar solicitudes
Aprenda a crear un proyecto basado en WSDL. SoapUI puede generar todas las consultas necesarias para usted; Lo único que tienes que hacer es comprobar que están cumplimentados correctamente y pulsar el botón “Enviar”. Una vez que haya desarrollado las habilidades para crear consultas válidas, debe dominar el arte de crear consultas incorrectas que causan errores.

Nivel 2: puedo realizar conjuntos de pruebas y casos de prueba
Empiece a realizar minipruebas automáticas. Los kits de prueba y los casos de prueba le permiten crear scripts de prueba de API, preparar datos para solicitudes y verificar automáticamente la respuesta recibida para garantizar que coincida con lo esperado. Al principio, pueden usarse simplemente como colecciones de consultas. Por ejemplo, si ha creado un defecto y desea comprobarlo rápidamente después de solucionarlo, puede asignar un kit de prueba independiente específicamente para solicitudes de defectos.

Nivel 3: puedo escribir afirmaciones
Después de dominar los casos de prueba, le resultará útil aprender cómo hacerlos verificables automáticamente. Después de esto, ya no necesitará buscar información sobre la respuesta con los ojos: si hay una verificación automática, los casos se marcarán en verde (si se pasa la verificación) o en rojo (si no se pasa). SoapUI proporciona un gran conjunto de afirmaciones posibles, pero las más convenientes y simples son Contiene y No contiene. Con su ayuda, podrá comprobar la presencia de un texto específico en la respuesta recibida. Estas comprobaciones también admiten búsquedas de expresiones regulares.

Nivel 4: use XPath y/o XQuery en aserciones
Para aquellos que están un poco familiarizados con la interfaz de usuario usando Selenium, el lenguaje XPath es algo familiar. En términos generales, XPath le permite buscar elementos en un documento XML. XQuery es una tecnología similar que puede utilizar XPath internamente; este lenguaje es mucho más poderoso, se parece a SQL. Ambos lenguajes se pueden utilizar en Afirmaciones. Con su ayuda, las comprobaciones son más específicas y estables, por lo que sus casos gozarán de mayor confianza.

Nivel 5: puedo escribir pruebas complejas usando pasos especiales

Los casos de prueba pueden contener no solo una solicitud, sino también varias (por ejemplo, cuando desea emular el escenario de usuario estándar "crear entidad" → "exportar entidad"). Puede haber otros pasos especiales entre solicitudes, por ejemplo:

  • Propiedades y transferencia de propiedad (ayuda a reutilizar datos y transferirlos entre solicitudes);
  • Solicitud JDBC (utilizada para recuperar datos de la base de datos);
  • Goto condicional (le permite hacer ramas o bucles en el caso de prueba);
  • Ejecute TestCase (ayuda a colocar algunas consultas típicas en casos de prueba separados y llamarlas cuando sea necesario).

Nivel 6: uso de scripts Groovy

SoapUI te permite escribir scripts Groovy en una variedad de lugares. El caso más simple es generar datos en la consulta misma usando inserciones $(=). Utilizo estos insertos todo el tiempo:

  • $(=nueva fecha().formato(“aaaa-MM-dd’T’HH:mm:ss”))– insertar la fecha y hora actuales en el formato requerido;
  • $(=java.util.UUID.randomUUID())– para insertar un GUID aleatorio formado correctamente.

Los scripts completos se pueden utilizar como pasos en casos y verificaciones. En algún momento, descubrirás que varios pasos especiales del quinto nivel se pueden reemplazar con un guión.

Nivel 7: uso de MockServices
SoapUI basado en WSDL puede generar objetos simulados. Un objeto simulado es la simulación más simple de un servicio. Con la ayuda de "simulacros", puede comenzar a escribir y depurar casos de prueba incluso antes de que el servicio esté realmente disponible para realizar pruebas. También se pueden utilizar como “talones” para servicios que no están disponibles temporalmente.

Nivel 8 – Dios SoapUI
Conoce la diferencia entre las versiones paga y gratuita de SoapUI y utiliza la API de SoapUI en su código. Utiliza complementos y ejecuta casos a través de la línea de comando y/o CI. Sus casos de prueba son simples y fáciles de mantener. En general, "te comiste al perro" con este instrumento. Me encantaría hablar con alguien que domine SoapUI a este nivel. Si eres uno, ¡regístrate en los comentarios!

Pruebas con lenguajes de programación

A continuación se muestra un ejemplo de cómo se ve una solicitud a la API de YandexSpeller, realizada con groovy-wslite:

importar wslite.soap.*
cliente def = nuevo SOAPClient("http://speller.yandex.net/services/spellservice?WSDL")
def respuesta = client.send(SOAPAction: "http://speller.yandex.net/services/spellservice/checkText") (
cuerpo (
CheckTextRequest("lang": "ru", "xmlns":"http://speller.yandex.net/services/spellservice") (
texto("error")
}
}
}
afirmar "error" == respuesta.CheckTextResponse.SpellResult.error.s.text()
afirmar "1" == [correo electrónico protegido]()

Hasta donde yo sé, todavía no existen marcos de alto nivel (como Rest-assured) para las pruebas SOAP, pero recientemente ha aparecido una herramienta interesante: el karate. Con su ayuda, puede describir casos para probar SOAP y REST en forma de scripts como Cucumber / Gherkin. Para muchos evaluadores, recurrir al kárate será una solución ideal, porque tales escenarios, en términos de la complejidad de la escritura y los casos de soporte, se ubicarán en algún punto intermedio entre el uso de SoapUI y la escritura de su propio marco para probar SOAP.

Conclusión

Es poco probable que alguna vez quieras probar SOAP solo por ti mismo (como podrías hacerlo con REST). Este es un protocolo pesado que se utiliza en soluciones empresariales serias. Pero su pesadez es al mismo tiempo un regalo para el evaluador: todas las tecnologías utilizadas están estandarizadas y existen herramientas de trabajo de alta calidad. Todo lo que se requiere del evaluador es el deseo de aprenderlos y utilizarlos.

Reunimos la misma lista de verificación de habilidades necesarias para un evaluador. Entonces, si recién está comenzando a probar los servicios SOAP, necesita saber y poder utilizar:

  • WSDL.
  • JABÓN.
  • Editores XML/XSD (a nivel de visualización XSD).
  • SoapUI en el nivel 1.

Como puede ver, el énfasis principal está en aprender los estándares; en SoapUI basta con poder ejecutar consultas. A medida que se sumerja en las pruebas SOAP, encontrará tareas que requerirán habilidades y conocimientos más serios, pero no debe intentar aprender todo de una vez. La coherencia a la hora de aumentar el nivel de complejidad de las tareas realizadas es mucho más importante. ¡Siguiendo esta recomendación algún día te darás cuenta de que te has convertido en un buen especialista en este campo!

sombreros 23 de julio de 2013 a las 01:09 pm

Escribir una aplicación cliente-servidor SOAP en PHP

  • PHP
  • Tutorial

¡Hola a todos!
Dio la casualidad de que recientemente comencé a desarrollar servicios web. Pero hoy el tema no es sobre mí, sino sobre cómo podemos escribir nuestro propio servicio web XML basado en el protocolo SOAP 1.2.

Espero que después de leer el tema puedas:

  • escribir su propia implementación de servidor de una aplicación web;
  • escribir su propia implementación cliente de una aplicación web;
  • escriba su propia descripción del servicio web (WSDL);
  • enviar las matrices del cliente del mismo tipo de datos al servidor.
Como habrás adivinado, toda la magia se hará usando PHP y las clases integradas SoapClient y SoapServer. Nuestro conejo será un servicio de envío de mensajes SMS.

1 planteamiento del problema

1.1 Límites

Al principio propongo abordar el resultado que lograremos al final del tema. Como se anunció anteriormente, escribiremos un servicio para enviar mensajes SMS y, más precisamente, recibiremos mensajes de diferentes fuentes a través del protocolo SOAP. Después de eso, consideraremos en qué forma llegan al servidor. Desafortunadamente, el proceso de poner en cola los mensajes para su posterior envío al proveedor está más allá del alcance de esta publicación por muchas razones.

1.2 ¿Qué datos cambiaremos?

¡Genial, hemos decidido los límites! El siguiente paso que hay que dar es decidir qué datos intercambiaremos entre el servidor y el cliente. Sobre este tema, le sugiero no dividirse por mucho tiempo y responder de inmediato las preguntas principales usted mismo:
  • ¿Qué datos mínimos se deben enviar al servidor para poder enviar un mensaje SMS a un suscriptor?
  • ¿Qué datos mínimos se deben enviar desde el servidor para satisfacer las necesidades del cliente?
Algo me dice que para esto necesitas enviar lo siguiente:
  • número de teléfono móvil y
  • texto del mensaje SMS.
En principio, estas dos características son suficientes para enviar, pero inmediatamente me imagino el caso de que te llegue un SMS con felicitaciones de cumpleaños a las 3 de la mañana, ¡o a las 4! ¡En este momento estaré muy agradecido con todos por no olvidarse de mí! Por lo tanto, también enviaremos al servidor y
  • fecha de envío del mensaje SMS.
Lo siguiente que me gustaría enviar al servidor es:
  • Tipo de mensaje.
Este parámetro no es obligatorio, pero nos puede resultar muy útil si necesitamos decirle rápidamente al jefe cuántos de nuestros clientes hemos “encantado” con nuestra noticia, y además sacar algunas bonitas estadísticas al respecto.

¡Y sin embargo, olvidé algo! Si reflexionamos un poco más, cabe destacar que el cliente puede enviar al servidor un mensaje SMS o varios a la vez. En otras palabras, un paquete de datos puede contener desde uno hasta infinitos mensajes.

Como resultado, obtenemos que para enviar un mensaje SMS necesitamos los siguientes datos:

  • número de teléfono móvil,
  • texto de mensaje SMS,
  • momento de envío del mensaje SMS al suscriptor,
  • tipo de mensaje.

Hemos respondido la primera pregunta, ahora necesitamos responder la segunda pregunta. Y tal vez me permitiré perder el tiempo un poco. Por tanto, desde el servidor enviaremos únicamente datos booleanos, cuyo significado tiene el siguiente significado:

  • VERDADERO: el paquete llegó exitosamente al servidor, pasó la autenticación y se puso en cola para enviarlo al proveedor de SMS.
  • FALSO – en todos los demás casos

¡Con esto concluye la descripción del planteamiento del problema! Y finalmente, vayamos a la parte divertida: ¡descubramos qué clase de bestia extraña es este SOAP!

2 ¿Qué es el jabón?

En general, inicialmente no planeé escribir nada sobre qué es SOAP y quería limitarme a enlaces al sitio web w3.org con las especificaciones necesarias, así como enlaces a Wikipedia. Pero al final decidí escribir una breve nota sobre este protocolo.

Y comenzaré mi historia con el hecho de que este protocolo de intercambio de datos pertenece a un subconjunto de protocolos basados ​​​​en el llamado paradigma RPC (Llamada a procedimiento remoto), cuya antípoda es REST (Transferencia de estado representacional). Puede leer más sobre esto en Wikipedia; los enlaces a los artículos se encuentran al final del tema. De estos artículos debemos entender lo siguiente: “El enfoque RPC permite el uso de una pequeña cantidad de recursos de red con una gran cantidad de métodos y un protocolo complejo. Con el enfoque REST, la cantidad de métodos y la complejidad del protocolo están estrictamente limitadas, lo que significa que la cantidad de recursos individuales puede ser grande”. Es decir, en relación con nosotros, esto significa que en el caso del enfoque RPC en el sitio siempre habrá una entrada (enlace) al servicio y qué procedimiento llamar para procesar los datos entrantes que transferimos junto con los datos, mientras con el enfoque REST en nuestro El sitio tiene muchas entradas (enlaces), cada una de las cuales acepta y procesa solo ciertos datos. Si alguien que lea sabe cómo explicar la diferencia entre estos enfoques de manera aún más simple, ¡asegúrese de escribir en los comentarios!

Lo siguiente que debemos saber sobre SOAP es que este protocolo utiliza el mismo XML como transporte, lo cual por un lado es muy bueno, porque Nuestro arsenal incluye inmediatamente todo el poder de una pila de tecnologías basadas en este lenguaje de marcado, a saber, XML-Schema, un lenguaje para describir la estructura de un documento XML (¡gracias Wikipedia!), que permite la validación automática de los datos recibidos por el servidor desde clientela.

¡Y ahora sabemos que SOAP es un protocolo utilizado para implementar llamadas a procedimientos remotos y utiliza XML como transporte! Si lee el artículo en Wikipedia, también podrá aprender desde allí que se puede usar en cualquier protocolo a nivel de aplicación, y no solo en combinación con HTTP (desafortunadamente, en este tema solo consideraremos SOAP sobre HTTP). ¿Y sabes qué es lo que más me gusta de todo esto? Si no hay conjeturas, te daré una pista: ¡JABÓN!... ¿Todavía no hay conjeturas?... ¿Estás seguro de que leíste el artículo en Wikipedia?... En general, no te torturaré más. Por lo tanto, iré directamente a la respuesta: "SOAP (del protocolo simple de acceso a objetos en inglés - simple protocolo acceso a objetos; hasta la especificación 1.2)". ¡Lo más destacable de esta línea está en cursiva! No sé qué conclusiones sacó de todo esto, pero veo lo siguiente: dado que este protocolo no puede llamarse "simple" de ninguna manera (y aparentemente incluso w3 está de acuerdo con esto), desde la versión 1.2 dejó de descifrarse de alguna manera ! Y pasó a ser conocido como SOAP, simplemente SOAP, punto.

Bueno, está bien, discúlpenme, me desvié un poco. Como escribí anteriormente, XML se utiliza como transporte y los paquetes que viajan entre el cliente y el servidor se denominan sobres SOAP. Si consideras la estructura general del sobre, te resultará muy familiar, porque... Se asemeja a la estructura de una página HTML. Tiene una sección principal - Envolver, que incluye secciones Encabezamiento Y Cuerpo, o Falla. EN Cuerpo se transmiten datos y es una sección obligatoria del sobre, mientras que Encabezamiento es opcional. EN Encabezamiento Se podrá transmitir autorización o cualquier otro dato que no esté directamente relacionado con los datos de entrada de los procedimientos del servicio web. Acerca de Falla no hay nada especial que decir, excepto que llega al cliente desde el servidor en caso de algún error.

Aquí termina mi historia de revisión sobre el protocolo SOAP (veremos los sobres en sí y su estructura con más detalle cuando nuestro cliente y servidor finalmente aprendan a ejecutarlos entre sí) y comienza una nueva: sobre el compañero SOAP llamado WSDL(Lenguaje de descripción de servicios web). Sí, sí, esto es precisamente lo que nos asusta a la mayoría de nosotros incluso de intentar implementar nuestra API en este protocolo. Como resultado, normalmente reinventamos nuestra rueda con JSON como transporte. Entonces, ¿qué es WSDL? WSDL es un lenguaje para describir servicios web y acceder a ellos, basado en el lenguaje XML (c) Wikipedia. Si esta definición no le aclara todo el significado sagrado de esta tecnología, ¡intentaré describirlo con mis propias palabras!

WSDL está diseñado para permitir a nuestros clientes comunicarse normalmente con el servidor. Para ello, el archivo con extensión “*.wsdl” describe la siguiente información:

  • ¿Qué espacios de nombres se utilizaron?
  • ¿Qué esquemas de datos se utilizaron?
  • ¿Qué tipos de mensajes espera el servicio web de los clientes?
  • Qué datos pertenecen a qué procedimientos de servicios web,
  • ¿Qué trámites contiene el servicio web?
  • ¿Cómo debe el cliente llamar a los procedimientos del servicio web?
  • ¿A qué dirección se deben enviar las llamadas de los clientes?
Como puede ver, este archivo es el servicio web completo. Al especificar la dirección del archivo WSDL en el cliente, ¡sabremos todo sobre cualquier servicio web! Como resultado, no necesitamos saber absolutamente nada sobre dónde se encuentra el servicio web. ¡Todo lo que necesitas saber es la ubicación de su archivo WSDL! Pronto descubriremos que SOAP no da tanto miedo como dicen los proverbios rusos.

3 Introducción al esquema XML

Ahora sabemos mucho sobre qué es SOAP, qué contiene y tenemos una descripción general de la pila de tecnología que lo rodea. Dado que, en primer lugar, SOAP es un método de interacción entre un cliente y un servidor, y el lenguaje de marcado XML se utiliza como transporte para ello, en esta sección entenderemos un poco cómo se produce la validación automática de datos utilizando esquemas XML.

La tarea principal del diagrama es describir la estructura de los datos que vamos a procesar. Todos los datos en esquemas XML se dividen en simple(escalar) y complejo(estructuras) tipos. Los tipos simples incluyen los siguientes tipos:

  • línea,
  • número,
  • valor booleano,
  • fecha.
Algo muy sencillo que no tiene extensiones en su interior. Su antípoda son los tipos complejos complejos. El ejemplo más simple de un tipo complejo que viene a la mente de todos son los objetos. Por ejemplo, un libro. El libro consta de propiedades: autor, Nombre, precio, número ISBN etc. Y estas propiedades, a su vez, pueden ser de tipos simples o complejos. Y la tarea del esquema XML es describir esto.

¡Sugiero no ir muy lejos y escribir un esquema XML para nuestro mensaje SMS! A continuación se muestra la descripción xml del mensaje SMS:

71239876543 Mensaje de prueba 2013-07-20T12:00:00 12
Nuestro diagrama de tipo complejo se verá así:


Esta entrada dice lo siguiente: Tenemos una variable " mensaje" tipo " Mensaje"y hay un tipo complejo llamado" Mensaje", que consta de un conjunto secuencial de elementos " teléfono" tipo cadena, « texto" tipo cadena, « fecha" tipo fechahora, « tipo" tipo decimal. Estos tipos son simples y ya están definidos en la descripción del esquema. ¡Felicidades! ¡Acabamos de escribir nuestro primer esquema XML!

Creo que el significado de los elementos " elemento" Y " tipo complejo"Todo te ha quedado más o menos claro, así que no nos centraremos más en ello y pasemos directamente al elemento compositor" secuencia" Cuando usamos el elemento compositor " secuencia“Les informamos que los elementos incluidos en el mismo deben ubicarse siempre en la secuencia especificada en el esquema, y ​​todos ellos son de obligado cumplimiento. ¡Pero no te desesperes! Hay dos elementos más del compositor en los esquemas XML: " elección" Y " todo" Compositor " elección" anuncia que debe haber uno de los elementos enumerados en él, y el compositor " todo» – cualquier combinación de los elementos enumerados.

Como recordarás, en el primer apartado del tema coincidimos en que en un paquete se pueden transmitir de uno a infinito mensajes SMS. Por lo tanto, propongo comprender cómo se declaran dichos datos en el esquema XML. La estructura general del paquete podría verse así:

71239876543 Mensaje de prueba 1 2013-07-20T12:00:00 12 71239876543 Mensaje de prueba N 2013-07-20T12:00:00 12
El diagrama para un tipo tan complejo se verá así:


El primer bloque contiene la conocida declaración del tipo complejo “ Mensaje" Si te diste cuenta, entonces en cada tipo simple incluido en " Mensaje", se han agregado nuevos atributos aclaratorios " minOcurre" Y " maxOcurre" Como puedes adivinar por el nombre, el primero ( minOcurre) indica que esta secuencia debe contener al menos un elemento de tipo " teléfono», « texto», « fecha" Y " tipo", mientras que el siguiente ( maxOcurre) el atributo nos declara que hay como máximo uno de esos elementos en nuestra secuencia. Como resultado, cuando escribimos nuestros propios esquemas para cualquier dato, ¡tenemos la opción más amplia sobre cómo configurarlos!

El segundo bloque del diagrama declara el elemento " lista de mensajes" tipo " Lista de mensajes" Está claro que " Lista de mensajes"es un tipo complejo que contiene al menos un elemento" mensaje", ¡pero el número máximo de dichos elementos no está limitado!

4 Escribe tu WSDL

¿Recuerdas que WSDL es nuestro servicio web? ¡Espero que lo recuerdes! Mientras lo escribimos, nuestro pequeño servicio web se ejecutará en él. Por lo tanto, sugiero no perder el tiempo.

Por lo general, para que todo nos funcione correctamente, necesitamos transferir un archivo WSDL con el tipo MIME correcto al cliente. Para hacer esto, necesita configurar su servidor web en consecuencia, es decir, establecer el tipo MIME para archivos con la extensión “*.wsdl” en la siguiente línea:

Aplicación/wsdl+xml
Pero en la práctica, normalmente envié el encabezado HTTP a través de PHP " texto/xml»:

Encabezado("Tipo de contenido: texto/xml; charset=utf-8");
¡Y todo funcionó muy bien!

Quiero advertirles de inmediato que nuestro sencillo servicio web tendrá una descripción bastante impresionante, así que no se alarmen, porque... La mayor parte del texto es obligatorio y, habiéndolo escrito una vez, ¡puedes copiarlo constantemente de un servicio web a otro!

Dado que WSDL es XML, debe escribir sobre esto directamente en la primera línea. El elemento raíz del archivo siempre debe llamarse " definiciones»:


Normalmente, WSDL consta de 4 o 5 bloques principales. El primer bloque es la definición de un servicio web o, en otras palabras, el punto de entrada.


Aquí dice que tenemos un servicio llamado " Servicio SMS" En principio, usted puede cambiar todos los nombres del archivo WSDL por el que desee, porque no juegan absolutamente ningún papel.

Luego de esto anunciamos que en nuestro servicio web " Servicio SMS"hay un punto de entrada ("puerto") llamado " PuertoServicioSms" Es a este punto de entrada al que se enviarán todas las solicitudes de los clientes al servidor. E indicar en el elemento “ DIRECCIÓN» enlace al archivo del controlador que aceptará solicitudes.

Una vez que hayamos definido el servicio web y especificado el punto de entrada, debemos vincularle los procedimientos admitidos:


Para ello, enumera qué operaciones y de qué forma se llamarán. Aquellos. para puerto " PuertoServicioSms"un enlace se define bajo el nombre" Enlace de servicio SMS", que tiene un tipo de llamada " rpc"y HTTP se utiliza como protocolo de transmisión. Por lo tanto, indicamos aquí que realizaremos una llamada RPC a través de HTTP. Después de esto describimos qué procedimientos ( operación) son compatibles con el servicio web. Apoyaremos sólo un procedimiento – “ enviarSms" ¡A través de este procedimiento nuestros maravillosos mensajes serán enviados al servidor! Una vez declarado el procedimiento, es necesario indicar en qué forma se transmitirán los datos. En este caso se indica que se utilizarán sobres SOAP estándar.

Después de eso, necesitamos vincular el procedimiento a los mensajes:


Para ello especificamos que nuestro enlace es de tipo " Tipo de puerto de servicio SMS" y en el elemento " tipo de puerto"con el nombre del mismo tipo indicamos la vinculación de procedimientos a mensajes. Y así, el mensaje entrante (del cliente al servidor) se llamará " enviarSmsSolicitud", y saliente (del servidor al cliente) " enviarSmsRespuesta" Como todos los nombres en WSDL, los nombres de los mensajes entrantes y salientes son arbitrarios.

Ahora necesitamos describir los mensajes en sí, es decir. entrantes y salientes:


Para ello añadimos los elementos " mensaje"con nombres" enviarSmsSolicitud" Y " enviarSmsRespuesta" respectivamente. En ellos indicamos que la entrada debe ser un sobre cuya estructura corresponda al tipo de datos " Pedido" Después de lo cual se devuelve un sobre del servidor que contiene el tipo de datos - " Respuesta».

Ahora tenemos que hacer un poco: ¡agregar una descripción de estos tipos a nuestro archivo WSDL! ¿Y cómo cree que describe el WSDL los datos entrantes y salientes? Creo que ya entendiste todo hace mucho tiempo y te dijiste que usar esquemas XML. ¡Y tendrás toda la razón!


¡Puedes felicitarnos! ¡Nuestro primer WSDL ha sido escrito! Y estamos un paso más cerca de lograr nuestro objetivo.
A continuación, veremos qué nos proporciona PHP para desarrollar nuestras propias aplicaciones distribuidas.

5 Nuestro primer servidor SOAP

Anteriormente escribí que para crear un servidor SOAP en PHP usaremos la clase integrada SoapServer. Para que todas las acciones posteriores se realicen de la misma manera que para mí, deberás modificar un poco tu PHP. Para ser aún más preciso, debes asegurarte de tener instalada la extensión “php-soap”. Lo mejor es leer cómo instalarlo en su servidor web en el sitio web oficial de PHP (consulte la lista de referencias).

Una vez instalado y configurado todo, necesitaremos crear un archivo en la carpeta raíz de tu hosting” smsservice.php» con el siguiente contenido:

setClass("SoapSmsGateWay"); //Inicia el servidor $server->handle();
Espero que no sea necesario explicar qué hay encima de la línea con la función “ini_set”. Porque allí se determina qué encabezados HTTP enviaremos desde el servidor al cliente y se configura el entorno. En la línea con "ini_set" desactivamos el almacenamiento en caché del archivo WSDL para que nuestros cambios surtan efecto inmediatamente en el cliente.

¡Ahora llegamos al servidor! Como puede ver, ¡todo el servidor SOAP solo ocupa tres líneas! En la primera línea, creamos una nueva instancia del objeto SoapServer y pasamos la dirección de nuestra descripción WSDL del servicio web a su constructor. Ahora sabemos que estará ubicado en la raíz del hosting en un archivo con el nombre autoexplicativo “ smsservice.wsdl.php" En la segunda línea, le indicamos al servidor SOAP qué clase se debe extraer para procesar el sobre recibido del cliente y devolver el sobre con la respuesta. Como habrás adivinado, es en esta clase donde se describirá nuestro único método. enviarSms. ¡En la tercera línea iniciamos el servidor! ¡Eso es todo, nuestro servidor está listo! ¡Con lo cual nos felicito a todos!

Ahora necesitamos crear el archivo WSDL. Para hacer esto, puedes simplemente copiar su contenido de la sección anterior, o tomarte la libertad y “plantillarlo” un poco:

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// esquemas.xmlsoap.org/wsdl/http/" nombre="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservicio.php" />
En esta etapa, deberíamos estar completamente satisfechos con el servidor resultante, porque Podemos registrar los sobres que llegan y luego analizar con calma los datos entrantes. Para que podamos recibir algo en el servidor, necesitamos un cliente. ¡Así que vamos a ello!

6 clientes SOAP en camino

En primer lugar, necesitamos crear un archivo en el que escribiremos el cliente. Como es habitual, lo crearemos en la raíz del host y lo llamaremos " cliente.php", y dentro escribiremos lo siguiente:

lista de mensajes = nueva lista de mensajes(); $req->listademensajes->mensaje = nuevo mensaje(); $req->listademensajes->mensaje->teléfono = "79871234567"; $req->messageList->message->text = "Mensaje de prueba 1"; $req->listademensajes->mensaje->fecha = "2013-07-21T15:00:00.26"; $req->listademensajes->mensaje->tipo = 15; $cliente = nuevo SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($cliente->sendSms($req));
Describamos nuestros objetos. Cuando escribimos el WSDL, describía tres entidades para el sobre entrante al servidor: Pedido, Lista de mensajes Y Mensaje. En consecuencia clases Pedido, Lista de mensajes Y Mensaje son reflejos de estas entidades en nuestro script PHP.

Una vez que hemos definido los objetos, necesitamos crear un objeto ( $requisito), que enviaremos al servidor. ¡Después vienen las dos líneas más queridas para nosotros! ¡Nuestro cliente SOAP! Lo creas o no, esto es suficiente para que nuestro servidor comience a recibir mensajes del cliente, ¡así como para que nuestro servidor los reciba y procese con éxito! En el primero de ellos creamos una instancia de la clase SoapClient y pasamos la dirección de ubicación del archivo WSDL a su constructor, y en los parámetros indicamos explícitamente que trabajaremos utilizando el protocolo SOAP versión 1.2. En la siguiente línea llamamos al método. enviarSms objeto $cliente e inmediatamente mostrar el resultado en el navegador.
¡Ejecutémoslo y veamos qué obtuvimos finalmente!

El siguiente objeto me fue devuelto desde el servidor:

Objeto (stdClass) público "estado" => booleano verdadero
Y esto es genial, porque... ¡Ahora sabemos con certeza que nuestro servidor está funcionando y no solo funciona, sino que también puede devolver algunos valores al cliente!

¡Ahora veamos el registro que mantenemos prudentemente en el lado del servidor! En su primera parte vemos los datos brutos que llegaron al servidor:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15
Este es el sobre. ¡Ahora ya sabes cómo luce! Pero es poco probable que estemos interesados ​​en verlo todo el tiempo, así que deserialicemos el objeto del archivo de registro y veamos si todo está bien:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1 " (longitud=37) public "fecha" => cadena "2013-07-21T15:00:00.26" (longitud=22) public "tipo" => cadena "15" (longitud=2)
Como puede ver, el objeto se deserializa correctamente, ¡por lo que quiero felicitarnos a todos! ¡A continuación nos espera algo más interesante! Es decir, enviaremos al cliente al servidor no solo un mensaje SMS, ¡sino un paquete completo (para ser más precisos, tres)!

7 Envío de objetos complejos

Pensemos en cómo podemos transferir una gran cantidad de mensajes al servidor en un solo paquete. ¡Probablemente la forma más sencilla sería organizar una matriz dentro del elemento messageList! Hagamos esto:

// crea un objeto para enviar al servidor $req = new Request(); $req->listademensajes = nueva Lista de mensajes(); $msg1 = nuevo mensaje(); $msg1->teléfono = "79871234567"; $msg1->text = "Mensaje de prueba 1"; $msg1->fecha = "2013-07-21T15:00:00.26"; $msj1->tipo = 15; $msg2 = nuevo mensaje(); $msg2->teléfono = "79871234567"; $msg2->text = "Mensaje de prueba 2"; $msg2->fecha = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuevo mensaje(); $msg3->teléfono = "79871234567"; $msg3->text = "Mensaje de prueba 3"; $msg3->fecha = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->listademensajes->mensaje = $msg1; $req->listademensajes->mensaje = $msg2; $req->listademensajes->mensaje = $msg3;
Nuestros registros indican que se recibió el siguiente paquete del cliente:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
¿Qué tontería dices? Y en cierto sentido tendrás razón, porque... Tan pronto como supimos que un objeto salió del cliente, llegó a nuestro servidor exactamente de la misma forma, en forma de sobre. Es cierto que los mensajes SMS no se serializaron en XML de la manera que necesitábamos: tuvieron que estar envueltos en elementos. mensaje, no en estructura. Ahora veamos en qué forma dicho objeto llega al método. enviarSms:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1" (longitud=37) public "date" => string "2013-07-21T15:00:00.26" (longitud=22) public " tipo" => cadena "15" (longitud=2) 1 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 2" (longitud= 37) pública "fecha" => cadena "2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "teléfono " => cadena "79871234567" (longitud=11) public "texto" => cadena "Mensaje de prueba 3" (longitud=37) public "fecha" => cadena "2014-08-22T16:01:10" (longitud= 19) público "tipo" => cadena "17" (longitud=2)
¿Qué nos aporta este conocimiento? Sólo que la ruta que elegimos no es correcta y no recibimos respuesta a la pregunta: "¿Cómo podemos obtener la estructura de datos correcta en el servidor?" Pero sugiero no desesperarse e intentar convertir nuestra matriz al tipo objeto:

$req->listademensajes->mensaje = (objeto)$req->lista de mensajes->mensaje;
En este caso recibiremos otro sobre:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
Entró en el método enviarSms el objeto tiene la siguiente estructura:

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => string "Mensaje de prueba 1" (longitud=37) public "date" => string "2013-07-21T15:00:00.26" (longitud=22) public " tipo" => cadena "15" (longitud=2) 1 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 2" (longitud= 37) pública "fecha" => cadena "2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "teléfono " => cadena "79871234567" (longitud=11) public "text" => cadena "Mensaje de prueba 3" (longitud=37) public "fecha" => cadena "2014-08-22T16:01:10" (longitud= 19) público "tipo" => cadena "17" (longitud=2)
En lo que a mí respecta, “la suma no cambia al cambiar los lugares de los términos” (c). Qué FALSO, Qué estructura– ¡aún no hemos logrado nuestro objetivo! Y para lograrlo, debemos asegurarnos de que en lugar de estos nombres incomprensibles se muestre nuestro nativo. mensaje. Pero el autor aún no sabe cómo lograrlo. Por tanto, lo único que podemos hacer es deshacernos del contenedor sobrante. En otras palabras, ahora nos aseguraremos de que en lugar de mensaje convertirse FALSO! Para hacer esto, cambie el objeto de la siguiente manera:

// crea un objeto para enviar al servidor $req = new Request(); $msg1 = nuevo mensaje(); $msg1->teléfono = "79871234567"; $msg1->text = "Mensaje de prueba 1"; $msg1->fecha = "2013-07-21T15:00:00.26"; $msj1->tipo = 15; $msg2 = nuevo mensaje(); $msg2->teléfono = "79871234567"; $msg2->text = "Mensaje de prueba 2"; $msg2->fecha = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuevo mensaje(); $msg3->teléfono = "79871234567"; $msg3->text = "Mensaje de prueba 3"; $msg3->fecha = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->listademensajes = $msg1; $req->listademensajes = $msg2; $req->listademensajes = $msg3; $req->listademensajes = (objeto)$req->lista de mensajes;
¿Qué pasa si tenemos suerte y aparece el nombre correcto en el diagrama? Para ello, veamos el sobre que llegó:

79871234567 Mensaje de prueba 1 2013-07-21T15:00:00.26 15 79871234567 Mensaje de prueba 2 2014-08-22T16:01:10 16 79871234567 Mensaje de prueba 3 2014-08-22T16:01:10 17
¡Sí, no ocurrió un milagro! FALSO– ¡no ganaremos! vino a enviarSms el objeto en este caso se verá así:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => matriz (tamaño=3) 0 => object(stdClass) public "phone" => cadena "79871234567" (longitud=11) public " texto" => cadena "Mensaje de prueba 1" (longitud=37) public "fecha" => cadena "2013-07-21T15:00:00.26" (longitud=22) public "tipo" => cadena "15" (longitud =2) 1 => objeto(stdClass) público "teléfono" => cadena "79871234567" (longitud=11) public "texto" => cadena "Mensaje de prueba 2" (longitud=37) pública "fecha" => cadena " 2014-08-22T16:01:10" (longitud=19) public "tipo" => cadena "16" (longitud=2) 2 => objeto(stdClass) public "phone" => cadena "79871234567" (longitud= 11) público "texto" => cadena "Mensaje de prueba 3" (longitud = 37) público "fecha" => cadena "2014-08-22T16:01:10" (longitud = 19) público "tipo" => cadena " 17" (largo=2)
Como dicen – ¡“Casi”! En esta nota (un poco triste), propongo resumir lentamente las cosas y sacar algunas conclusiones por nosotros mismos.

8 Conclusión

¡Finalmente llegamos aquí! Averigüemos qué puedes hacer ahora:
  • puedes escribir el archivo WSDL necesario para tu servicio web;
  • puedes escribir fácilmente tu propio cliente que pueda comunicarse con el servidor vía SOAP;
  • puedes escribir tu propio servidor que se comunique con el mundo exterior vía SOAP;
  • puedes enviar matrices del mismo tipo de objetos al servidor desde tu cliente (con algunas restricciones).
También hicimos algunos descubrimientos durante nuestra pequeña investigación:
  • la clase nativa SoapClient no serializa correctamente estructuras de datos del mismo tipo en XML;
  • al serializar una matriz a XML, se crea un elemento adicional llamado estructura;
  • al serializar un objeto a XML se crea un elemento extra llamado FALSO;
  • FALSO menos malvado que estructura debido al hecho de que el sobre es más compacto (no se agregan espacios de nombres adicionales al encabezado XML del sobre);
  • Desafortunadamente, la clase SoapServer no valida automáticamente los datos del sobre con nuestro esquema XML (quizás otros servidores tampoco lo hagan).



Arriba