Frage Wie übergibt man "Null" (ein richtiger Nachname!) An einen SOAP-Webdienst in ActionScript 3?


Wir haben einen Angestellten, dessen Nachname Null ist. Unsere Mitarbeiter-Lookup-Anwendung wird beendet, wenn der Nachname als Suchbegriff verwendet wird (was jetzt häufig der Fall ist). Der Fehler, der empfangen wurde (danke Fiddler!) Ist:

<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>

Nett, nicht wahr?

Der Parametertyp ist string.

Ich benutze:

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

Beachten Sie, dass der Fehler auftritt nicht auftreten, wenn der Webservice als Objekt von einer ColdFusion-Seite aufgerufen wird.


4474
2017-12-16 00:42


Ursprung


Antworten:


 Aufspüren

Zuerst dachte ich, das wäre ein Nötigungsproblem null wurde genervt "null" und ein Test von "null" == null ging vorbei. Es ist nicht. Ich war nahe dran, aber so sehr, sehr falsch. Das tut mir leid!

Ich habe seitdem viel getan fummeln auf wonderfl.net und durch den Code in mx.rpc.xml.*. In Zeile 1795 von XMLEncoder (in der 3.5 Quelle), in setValue, die ganze XMLEncoding läuft darauf hinaus

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

Das ist im Wesentlichen das Gleiche wie:

currentChild.appendChild("null");

Dieser Code gibt meiner Originalgeige nach ein leeres XML-Element zurück. Aber warum?

 Ursache

Laut Kommentator Justin Mclean auf Fehlerbericht FLEX-33664Das Folgende ist der Schuldige (siehe die letzten beiden Tests in meinem Geige die das verifizieren):

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
}

Wann currentChild.appendChild ist die Zeichenfolge übergeben "null"Es konvertiert es zuerst in ein XML-Stammelement mit Text nullund testet dann dieses Element gegen das Nullliteral. Dies ist ein schwacher Gleichheitstest. Entweder wird das XML mit null zum Nulltyp gezwungen, oder der Nulltyp wird zu einem root xml-Element mit der Zeichenfolge "null" gezwungen, und der Test wird bestanden, wo er wohl fehlschlagen sollte. Eine Lösung könnte sein, immer zu verwenden strenge Gleichheit testet beim Überprüfen von XML (oder irgendetwas, wirklich) auf "nullness".

Lösung

Der einzige vernünftige Workaround, den ich mir vorstellen kann, ist, diesen Fehler in jeder verdammten Version von ActionScript zu beheben, indem ich die Felder für "null" und entkomme ihnen als CDATA-Werte. 

CDATA-Werte sind die am besten geeignete Methode, um einen ganzen Textwert zu mutieren, der andernfalls zu Codierungs- / Decodierungsproblemen führen würde. Die Hex-Codierung ist beispielsweise für einzelne Zeichen gedacht. CDATA-Werte werden bevorzugt, wenn Sie den gesamten Text eines Elements umgehen. Der Hauptgrund dafür ist, dass es die menschliche Lesbarkeit beibehält.


1049
2017-08-01 17:31



Auf der xkcd-Notiz, das Bobby Tables Webseite hat gute Ratschläge, um die fehlerhafte Interpretation von Benutzerdaten (in diesem Fall die Zeichenkette "Null") in SQL-Abfragen in verschiedenen Sprachen zu vermeiden, darunter ColdFusion.

Aus der Frage, dass dies die Ursache des Problems ist, ist nicht klar, und angesichts der Lösung, die in einem Kommentar zur ersten Antwort notiert wurde (Einbetten der Parameter in eine Struktur), scheint es wahrscheinlich, dass es sich um etwas anderes handelte.


285
2018-04-27 20:00



Das Problem könnte im SOAP-Encoder von Flex liegen. Versuchen Sie, den SOAP-Encoder in Ihrer Flex-Anwendung zu erweitern und das Programm zu debuggen, um zu sehen, wie der Nullwert behandelt wird. Meine Vermutung ist, es ist als bestanden NaN (Keine Nummer) Dies wird SOAP Message Unmarshalling Prozess irgendwann (vor allem in JBoss 5 Server ...). Ich erinnere mich daran, den SOAP-Encoder zu erweitern und explizit zu überprüfen, wie NaN gehandhabt wird.

(Nebenbei bemerkt, wird von Ihnen erwartet, dass Sie etwas Nützliches tun, wenn Mitarbeiter-ID Null ist, ist dies kein Validierungsproblem? Ich könnte mich irren, da ich die Anforderung kaum kenne ...)


235
2018-01-16 08:13



@ doc_180 hatte das richtige Konzept, außer dass er sich auf Zahlen konzentriert, während das ursprüngliche Poster Probleme mit Strings hatte.

Die Lösung ist das Ändern der mx.rpc.xml.XMLEncoder Datei. Dies ist Linie 121

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

[Ich schaute auf Flex 4.5.1 SDK; Zeilennummern können in anderen Versionen abweichen]

Im Grunde schlägt die Validierung fehl, weil "Inhalt null ist" und daher Ihr Argument dem ausgehenden SOAP-Paket nicht hinzugefügt wird; wodurch der fehlende Parameterfehler verursacht wird.

Sie müssen diese Klasse erweitern, um die Validierung zu entfernen. Dann gibt es einen großen Schneeball in der Kette, SOAPEncoder zu ändern, um Ihren modifizierten XMLEncoder zu verwenden, und dann Operation zu ändern, um Ihren geänderten SOAPEncoder zu verwenden, und WebService dann zu bearbeiten, um Ihre alternative Operation-Klasse zu verwenden.

Ich habe ein paar Stunden damit verbracht, muss aber weitermachen. Es wird wahrscheinlich einen oder zwei Tage dauern.

Sie können vielleicht nur die XMLEncoder-Zeile reparieren und ein paar Affe-Patches ausführen, um Ihre eigene Klasse zu verwenden.

Ich werde auch hinzufügen, dass, wenn Sie RemoteObject / AMF mit ColdFusion verwenden, die Null ohne Probleme übergeben wird.


11/16/2013 Aktualisierung:

Ich habe eine neuere Ergänzung zu meinem letzten Kommentar über RemoteObject / AMF. Wenn Sie CF10 verwenden; Dann werden Eigenschaften mit einem Nullwert für ein Objekt vom serverseitigen Objekt entfernt. Sie müssen also vor dem Zugriff auf die Existenz der Eigenschaften prüfen oder Sie erhalten einen Laufzeitfehler. Sieh dir das an:

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

Dies ist eine Verhaltensänderung gegenüber CF9; wo die NULL-Eigenschaften in leere Zeichenfolgen umgewandelt würden.


Bearbeiten 12/6/2013

Da es eine Frage darüber gab, wie Nullwerte hier behandelt werden, ist eine schnelle Beispielanwendung, um zu demonstrieren, wie sich eine Zeichenkette "null" auf das reservierte Wort null bezieht.

<?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>

Die Ablaufverfolgung ist:

Die Nullzeichenfolge ist nicht gleich dem reservierten Wort Null, wobei die Bedingung! = verwendet wird

Die Nullzeichenfolge ist nicht gleich dem reservierten Wort null, wenn die Bedingung == verwendet wird

Die Nullzeichenfolge ist nicht gleich dem reservierten Wort "null" mit der Bedingung ===


125
2018-05-03 15:51



Übersetzen Sie alle Zeichen in ihre Hex-Entity-Äquivalente. In diesem Fall, Null würde in umgewandelt werden &#4E;&#75;&#6C;&#6C;


62
2018-04-30 19:03



Zeichnend a null Wert in ActionScript Wird die Zeichenfolge geben "NULL". Mein Verdacht ist, dass jemand entschieden hat, dass es daher eine gute Idee ist, die Saite zu entschlüsseln "NULL" wie null, verursacht die Bruchstelle, die Sie hier sehen - wahrscheinlich, weil sie vorbeigingen null Objekte und erhalten Strings in der Datenbank, wenn sie das nicht wollten (also achten Sie auch auf diese Art von Fehler).


49
2018-04-28 20:15



Als Hack könnte man eine spezielle Behandlung auf der Client-Seite in Erwägung ziehen, die 'Null'-Zeichenfolge in etwas umwandelt, das niemals vorkommen wird, zum Beispiel XXNULLXX, und zurück auf dem Server konvertieren.

Es ist nicht schön, aber es kann das Problem für solch einen Grenzfall lösen.


36
2018-04-28 08:43



Nun, ich denke, dass die Flex-Implementierung des SOAP-Encoders Nullwerte falsch zu serialisieren scheint. Serialisieren sie als String Null scheint keine gute Lösung zu sein. Die formal korrekte Version scheint einen Nullwert zu übergeben als:

<childtag2 xsi:nil="true" />

Der Wert von "Null" wäre also nichts anderes als eine gültige Zeichenfolge, die genau das ist, wonach Sie suchen.

Ich denke, dies in Apache Flex behoben zu bekommen, sollte nicht so schwierig sein. Ich würde empfehlen, eine Jira-Ausgabe zu öffnen oder die Jungs der apache-flex-Mailingliste zu kontaktieren. Dies würde jedoch nur die Client-Seite beheben. Ich kann nicht sagen, ob ColdFusion mit so kodierten Nullwerten arbeiten kann.

Siehe auch den Blogbeitrag von Radu Cotescu So senden Sie Nullwerte in SoapUI-Anforderungen.


30
2017-07-17 07:56



Es ist ein Klud, aber vorausgesetzt, es gibt eine Mindestlänge für SEARCHSTRINGzum Beispiel 2 Zeichen, substring das SEARCHSTRING Parameter am zweiten Zeichen und übergeben Sie es stattdessen als zwei Parameter: SEARCHSTRING1 ("Nu") und SEARCHSTRING2 ("ll").  Concatenate sie wieder zusammen, wenn die Abfrage an die Datenbank ausgeführt wird.


21
2018-04-28 19:48