flex actionscript soap coldfusion wsdl

flex - ¿Cómo pasar “Null”(un apellido real) a un servicio web SOAP en ActionScript 3?



coldfusion wsdl (9)

Rastreando hacia abajo

Al principio, pensé que se trataba de un error de coerción donde null estaba siendo forzado a "null" y se pasaba una prueba de "null" == null . No es. Estaba cerca, pero muy, muy mal. ¡Lo siento por eso!

Desde entonces he hecho muchos trucos en wonderfl.net y rastreo a través del código en mx.rpc.xml.* . En la línea 1795 de XMLEncoder (en la fuente 3.5), en setValue , todos los códigos XMLE se reducen a

currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));

que es esencialmente lo mismo que:

currentChild.appendChild("null");

Este código, según mi violín original, devuelve un elemento XML vacío. ¿Pero por qué?

Porque

Según el comentarista Justin Mclean en el informe de error FLEX-33664 , el siguiente es el culpable (vea las dos últimas pruebas en mi violín que verifican esto):

var thisIsNotNull:XML = <root>null</root>; if(thisIsNotNull == null){ // always branches here, as (thisIsNotNull == null) strangely returns true // despite the fact that thisIsNotNull is a valid instance of type XML }

Cuando currentChild.appendChild pasa la cadena "null" , primero la convierte en un elemento XML raíz con texto null , y luego prueba ese elemento contra el literal nulo. Esta es una prueba de igualdad débil, por lo que el XML que contiene nulo se aplica al tipo nulo o el tipo nulo se aplica a un elemento xml raíz que contiene la cadena "nula", y la prueba pasa donde podría fallar. Una solución podría ser utilizar siempre pruebas de igualdad estrictas cuando se comprueba XML (o cualquier cosa, realmente) en busca de "nulidad".

Solución

La única solución razonable que se me ocurre, aparte de solucionar este error en cada versión maldita de ActionScript, es probar los campos para "nulos" y escapar de ellos como valores CDATA .

Los valores CDATA son la forma más adecuada de mutar un valor de texto completo que, de lo contrario, causaría problemas de codificación / decodificación. La codificación hexadecimal, por ejemplo, está pensada para caracteres individuales. Se prefieren los valores CDATA cuando se escapa el texto completo de un elemento. La razón principal de esto es que mantiene la legibilidad humana.

Tenemos un empleado cuyo apellido es nulo. Nuestra aplicación de búsqueda de empleados se cancela cuando ese apellido se usa como término de búsqueda (lo que sucede ahora con bastante frecuencia). El error recibido (gracias Fiddler!) Es:

<soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.MissingArgumentException : The SEARCHSTRING parameter to the getFacultyNames function is required but was not passed in.]</faultstring>

Lindo eh

El tipo de parámetro es string .

Estoy usando:

  • WSDL (SOAP)
  • Flex 3.5
  • ActionScript 3
  • ColdFusion 8

Tenga en cuenta que el error no se produce al llamar al servicio web como un objeto desde una página de ColdFusion.


@ doc_180 tenía el concepto correcto, excepto que está centrado en los números, mientras que el póster original tenía problemas con las cuerdas.

La solución es cambiar el archivo mx.rpc.xml.XMLEncoder . Esta es la línea 121

if (content != null) result += content;

[Miré Flex 4.5.1 SDK; los números de línea pueden diferir en otras versiones]

Básicamente, la validación falla porque "el contenido es nulo" y, por lo tanto, su argumento no se agrega al paquete SOAP saliente; causando así el error de parámetro que falta.

Tienes que ampliar esta clase para eliminar la validación. Luego hay una gran bola de nieve en la cadena, modificando SOAPEncoder para usar su XMLEncoder modificado, y luego modificando la Operación para usar su SOAPEncoder modificado, y luego reduciendo el Servicio Web para usar su clase de Operación alternativa.

Pasé unas horas en ello, pero necesito seguir adelante. Probablemente tome un día o dos.

Es posible que solo puedas corregir la línea XMLEncoder y hacer algunos parches de mono para usar tu propia clase.

También agregaré que si cambia a usar RemoteObject / AMF con ColdFusion, el nulo se pasa sin problemas.

16/11/2013 actualización :

Tengo una adición más reciente a mi último comentario sobre RemoteObject / AMF. Si está utilizando CF10; luego, las propiedades con un valor nulo en un objeto se eliminan del objeto del lado del servidor. Por lo tanto, debe verificar la existencia de las propiedades antes de acceder a ellas o obtendrá un error de tiempo de ejecución. Compruebe así:

<cfif (structKeyExists(arguments.myObject,''propertyName'')> <!--- no property code ---> <cfelse> <!--- handle property normally ---> </cfif>

Este es un cambio en el comportamiento de CF9; donde las propiedades nulas se convertirían en cadenas vacías.

Editar 12/6/2013

Como hubo una pregunta sobre cómo se tratan los nulos aquí, hay una aplicación de muestra rápida para demostrar cómo una cadena "null" se relacionará con la palabra reservada null.

<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protected function application1_initializeHandler(event:FlexEvent):void { var s :String = "null"; if(s != null){ trace(''null string is not equal to null reserved word using the != condition''); } else { trace(''null string is equal to null reserved word using the != condition''); } if(s == null){ trace(''null string is equal to null reserved word using the == condition''); } else { trace(''null string is not equal to null reserved word using the == condition''); } if(s === null){ trace(''null string is equal to null reserved word using the === condition''); } else { trace(''null string is not equal to null reserved word using the === condition''); } } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> </s:Application>

La salida de seguimiento es:

la cadena nula no es igual a la palabra reservada nula usando la condición! =

la cadena nula no es igual a la palabra reservada nula usando la condición ==

la cadena nula no es igual a la palabra reservada nula usando la condición ===


Bueno, supongo que la implementación de Flex del codificador SOAP parece serializar incorrectamente los valores nulos. Serializarlos como un String Null no parece ser una buena solución. La versión oficialmente correcta parece ser pasar un valor nulo como:

<childtag2 xsi:nil="true" />

Por lo tanto, el valor de "Null" no sería más que una cadena válida, que es exactamente lo que está buscando.

Supongo que arreglar esto en Apache Flex no debería ser tan difícil de hacer. Recomendaría abrir un problema de Jira o ponerse en contacto con los tipos de la lista de correo de apache-flex. Sin embargo esto solo solucionaría el lado del cliente. No puedo decir si ColdFusion podrá trabajar con valores nulos codificados de esta manera.

Consulte también la publicación del blog de Radu Cotescu Cómo enviar valores nulos en solicitudes de soapUI .


Como hack, podría considerar tener un manejo especial en el lado del cliente, convertir la cadena ''Nula'' en algo que nunca ocurrirá, por ejemplo, XXNULLXX y volver a convertir en el servidor.

No es bonito, pero puede resolver el problema para tal caso de límite.


El problema podría estar en el codificador SOAP de Flex. Intente extender el codificador SOAP en su aplicación Flex y depure el programa para ver cómo se maneja el valor nulo. Mi conjetura es, se pasa como NaN (no un número). Esto ensuciará el proceso de desaprobación del mensaje SOAP en algún momento (especialmente en el JBoss 5 ...). Recuerdo que amplié el codificador SOAP y realicé una comprobación explícita de cómo se maneja NaN.

(En una nota al margen, ¿se espera que haga algo útil si la identificación del empleado es nula, no es este un problema de validación? Podría estar equivocado, ya que apenas conozco el requisito ...)


En la nota de xkcd , el sitio web de Bobby Tables tiene buenos consejos para evitar la interpretación incorrecta de los datos del usuario (en este caso, la cadena "Null") en consultas SQL en varios idiomas, incluido ColdFusion .

No queda claro a partir de la pregunta que esta es la fuente del problema y, dada la solución anotada en un comentario a la primera respuesta (incrustar los parámetros en una estructura), parece probable que se tratara de otra cosa.


Es un kludge, pero asumiendo que hay una longitud mínima para SEARCHSTRING , por ejemplo 2 caracteres, SEARCHSTRING parámetro SEARCHSTRING en el segundo carácter y SEARCHSTRING1 ("Nu") como dos parámetros: SEARCHSTRING1 ("Nu") y SEARCHSTRING2 ("ll"). Concatenate nuevo juntos al ejecutar la consulta a la base de datos.


Stringifying un valor null en ActionScript dará la cadena "NULL" . Mi sospecha es que alguien ha decidido que es, por lo tanto, una buena idea descifrar la cadena "NULL" como null , causando la rotura que se ve aquí, probablemente porque pasaron objetos null y obtuvieron cadenas en la base de datos, cuando no querían eso (así que asegúrate de revisar ese tipo de error).


Traducir todos los caracteres en sus equivalentes de entidad hexadecimal. En este caso, Null se convertiría en &#4E;&#75;&#6C;&#6C;