Tenemos un empleado cuyo apellido es Nulo. Nuestra aplicación de búsqueda de empleados se anula cuando se usa ese apellido como término de búsqueda (que ahora es bastante frecuente). 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:
Tenga en cuenta que el error no se produce al llamar al servicio web como un objeto desde una página de ColdFusion.
apache-flex
actionscript
soap
coldfusion
wsdl
cuenta
fuente
fuente
Respuestas:
Rastreándolo
Al principio pensé que se trataba de un error de coerción en el que se
null
estaba coaccionando"null"
y"null" == null
estaba pasando una prueba . No es. Estaba cerca, pero muy, muy mal. ¡Lo siento por eso!Desde entonces, he jugado mucho en wonderfl.net y he rastreado el código en
mx.rpc.xml.*
. En la línea 1795 deXMLEncoder
(en la fuente 3.5), ensetValue
, todo el XMLEncoding se reduce aque es esencialmente lo mismo que:
Este código, de acuerdo con 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):
Cuando
currentChild.appendChild
se pasa la cadena"null"
, primero la convierte en un elemento XML raíz con textonull
, 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 coacciona al tipo nulo o el tipo nulo se coacciona a un elemento xml raíz que contiene la cadena "nulo", y la prueba pasa donde posiblemente podría fallar. Una solución podría ser usar siempre pruebas de igualdad estrictas al verificar XML (o cualquier cosa, realmente) para "nulidad".Solución
La única solución razonable que se me ocurre, salvo corregir este error en cada maldita versión de ActionScript, es probar los campos para "nulo" y escapar de ellos como valores CDATA .Los valores CDATA son la forma más apropiada de mutar un valor de texto completo que de otra forma causaría problemas de codificación / decodificación. La codificación hexadecimal, por ejemplo, está destinada a caracteres individuales. Se prefieren los valores CDATA cuando se escapa del texto completo de un elemento. La razón principal de esto es que mantiene la legibilidad humana.
fuente
En la nota 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 "Nulo") 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 (incrustando los parámetros en una estructura) parece probable que se tratara de otra cosa.
fuente
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.
Supongo que se pasa como NaN (no es un número). Esto estropeará el proceso de desorganización de mensajes SOAP en algún momento (más notablemente en el servidor JBoss 5 ...). Recuerdo extender el codificador SOAP y realizar una comprobación explícita de cómo se maneja NaN.
fuente
@ doc_180 tenía el concepto correcto, excepto que está enfocado en los números, mientras que el póster original tenía problemas con las cadenas.
La solución es cambiar el
mx.rpc.xml.XMLEncoder
archivo. Esta es la línea 121:(Miré el SDK de Flex 4.5.1; 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 faltante.
Tiene que extender 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 Operation para usar su SOAPEncoder modificado, y luego moidfying WebService para usar su clase de Operación alternativa.
Pasé unas horas en eso, pero necesito seguir adelante. Probablemente tomará uno o dos días.
Es posible que pueda arreglar la línea XMLEncoder y hacer algunos parches de mono para usar su propia clase.
También agregaré que si cambia a usar RemoteObject / AMF con ColdFusion, el valor nulo se pasa sin problemas.
11/16/2013 actualización :
Tengo una adición más reciente a mi último comentario sobre RemoteObject / AMF. Si está utilizando ColdFusion 10; entonces 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 propiedades antes de acceder a ella o obtendrá un error de tiempo de ejecución.
Comprueba así:
Este es un cambio de comportamiento de ColdFusion 9; donde las propiedades nulas se convertirían en cadenas vacías.
Editar 06/12/2013
Como había una pregunta sobre cómo se tratan los nulos, aquí hay una aplicación de muestra rápida para demostrar cómo una cadena "nulo" se relacionará con la palabra reservada nulo.
La salida de rastreo es:
fuente
content
está la cadena"null"
, y "null" == null devuelve falso, por lo que la prueba se comporta como se esperaba. En cambio, creo que el problema es una mezcla de cómo XML.appendChild maneja un argumento de cadena, y cómo un elemento XML raíz que contiene solo la cadena "nulo" se puede convertir en un literalnull
.true
aquí es el comportamiento deseado. Si sucediera lo contrario, esto descartaría la cadena "nula" del proceso de codificación, que de hecho sería la causa del problema. Sin embargo, debido a que esta prueba tiene éxito, el codificador continúa hasta que XML.appendChild la descarta debido a un error de coerción.var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s);
a su muestra de código.Traduce todos los caracteres a sus equivalentes de entidad hexadecimal. En este caso,
Null
se convertiría enE;KC;C;
fuente
La cadena de un
null
valor en ActionScript dará la cadena"NULL"
. Mi sospecha es que alguien ha decidido que es, por lo tanto, una buena idea decodificar la cadena ,"NULL"
ya quenull
causa la rotura que ves aquí, probablemente porque estaban pasandonull
objetos y obteniendo cadenas en la base de datos, cuando no querían eso (así que asegúrese de verificar ese tipo de error también).fuente
Como truco, podría considerar tener un manejo especial en el lado del cliente, convirtiendo la cadena 'Nulo' en algo que nunca ocurrirá, por ejemplo, XXNULLXX y volviendo a convertir en el servidor.
No es bonito, pero puede resolver el problema para tal caso límite.
fuente
Null
?Bueno, supongo que la implementación de Flex del codificador SOAP parece serializar valores nulos incorrectamente. Serializarlos como String Null no parece ser una buena solución. La versión formalmente correcta parece ser pasar un valor nulo como:
Por lo tanto, el valor de "Nulo" no sería más que una cadena válida, que es exactamente lo que está buscando.
Supongo que solucionar esto en Apache Flex no debería ser tan difícil de hacer. Recomendaría abrir un problema de Jira o contactar a los chicos de la lista de correo 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 de blog de Radu Cotescu Cómo enviar valores nulos en solicitudes de soapUI .
fuente
null
valor verdadero correctamente, estableciendoxsi:nil="true"
el elemento. El problema en realidad parece estar en la forma en que elXML
tipo ActionScript en sí (no el codificador) maneja la cadena"null"
.Es un error, pero suponiendo que haya una longitud mínima para
SEARCHSTRING
, por ejemplo, 2 caracteres,substring
elSEARCHSTRING
parámetro en el segundo carácter y pasarlo como dos parámetros en su lugar:SEARCHSTRING1 ("Nu")
ySEARCHSTRING2 ("ll").
Concatenate
volver a unirlos al ejecutar la consulta a la base de datos.fuente
n
,u
,l
tiene una semántica especial en XML. "NULL" y "<! [CDATA [NULL]]>>" son idénticos a un analizador XML.NULL
, sino ser pedante<blah>null</blah>
y<blah><![CDATA[null]]>
no es lo mismo para un analizador XML. Ellos deben producir los mismos resultados, sin embargo, el flujo lógico para el manejo de ellos es diferente. Es este efecto el que estamos explotando como una solución al error en la implementación de flex XML. Abogo por esto sobre otros enfoques, ya que conserva la legibilidad del texto y no tiene efectos secundarios para otros analizadores.