Mamy pracownika o nazwisku Null. Nasza aplikacja do wyszukiwania pracowników zostaje zabita, gdy to nazwisko jest używane jako wyszukiwane hasło (co zdarza się obecnie dość często). Otrzymany błąd (dzięki Fiddler!) To:
<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>
Urocze, co?
Typ parametru to string
.
Ja używam:
Zauważ, że błąd nie występuje podczas wywoływania usługi internetowej jako obiektu ze strony ColdFusion.
apache-flex
actionscript
soap
coldfusion
wsdl
rachunek
źródło
źródło
Odpowiedzi:
Śledzenie tego
Na początku myślałem, że to błąd przymusu, do którego
null
zmuszano mnie,"null"
a test"null" == null
zdawał. To nie jest. Byłem blisko, ale bardzo, bardzo źle. Przepraszam za to!Od tego czasu robiłem wiele skrzypków na wonderfl.net i śledziłem kod w
mx.rpc.xml.*
. W linii 1795XMLEncoder
(w źródle 3.5), wsetValue
, całe XMLEncoding sprowadza się doktóry jest zasadniczo taki sam jak:
Ten kod, zgodnie z moim oryginalnym skrzypkiem, zwraca pusty element XML. Ale dlaczego?
Przyczyna
Według komentatora Justina Mcleana w raporcie o błędach FLEX-33664 , winowajcą jest następujący (zobacz dwa ostatnie testy w mojej skrzypce, które to potwierdzają):
Po
currentChild.appendChild
przekazaniu ciągu"null"
najpierw konwertuje go do głównego elementu XML z tekstemnull
, a następnie testuje ten element pod kątem literału zerowego. To jest słaby test równości, więc albo XML zawierający null jest przymuszany do typu null, albo typ null jest przymuszany do głównego elementu xml zawierającego ciąg „null”, a test przechodzi tam, gdzie prawdopodobnie powinien zawieść. Jedną z poprawek może być zawsze stosowanie ścisłych testów równości podczas sprawdzania XML (lub cokolwiek, naprawdę) pod kątem „nieważności”.Rozwiązanie
Jedynym rozsądnym obejściem, jakie mogę wymyślić, poza naprawieniem tego błędu w każdej przeklętej wersji ActionScript, jest przetestowanie pól pod kątem „null” i uniknięcie ich jako wartości CDATA .Wartości CDATA są najbardziej odpowiednim sposobem na zmutowanie całej wartości tekstowej, która w innym przypadku spowodowałaby problemy z kodowaniem / dekodowaniem. Na przykład kodowanie szesnastkowe jest przeznaczone dla pojedynczych znaków. Wartości CDATA są preferowane, gdy unikasz całego tekstu elementu. Głównym powodem tego jest to, że zachowuje czytelność dla ludzi.
źródło
W nocie xkcd The Bobby Stoły strona ma dobrą radę dla uniknięcia niewłaściwej interpretacji danych użytkownika (w tym przypadku napis „null”) w zapytań SQL w różnych językach, w tym ColdFusion .
Z pytania nie wynika jasno, że jest to źródło problemu, a biorąc pod uwagę rozwiązanie zanotowane w komentarzu do pierwszej odpowiedzi (osadzenie parametrów w strukturze), wydaje się prawdopodobne, że było to coś innego.
źródło
Problem może dotyczyć kodera SOAP Flex. Spróbuj rozszerzyć koder SOAP w aplikacji Flex i debuguj program, aby zobaczyć, jak obsługiwana jest wartość null.
Domyślam się, że jest przekazywany jako NaN (Not a Number). To kiedyś zepsuje proces usuwania wiadomości z protokołu SOAP (przede wszystkim na serwerze JBoss 5 ...). Pamiętam rozszerzenie enkodera SOAP i wyraźne sprawdzenie, jak obsługiwany jest NaN.
źródło
@ doc_180 miał właściwą koncepcję, tyle że skupiał się na liczbach, podczas gdy oryginalny plakat miał problemy z łańcuchami.
Rozwiązaniem jest zmiana
mx.rpc.xml.XMLEncoder
pliku. To jest linia 121:(Patrzyłem na Flex 4.5.1 SDK; numery linii mogą się różnić w innych wersjach.)
Zasadniczo sprawdzanie poprawności kończy się niepowodzeniem, ponieważ „treść jest pusta” i dlatego argument nie jest dodawany do wychodzącego pakietu SOAP; powodując w ten sposób błąd braku parametru.
Musisz rozszerzyć tę klasę, aby usunąć sprawdzanie poprawności. Następnie jest duża śnieżka w górę łańcucha, modyfikująca SOAPEncoder, aby używał zmodyfikowanego XMLEncodera, a następnie modyfikuje Operację, aby używać zmodyfikowanego SOAPEncodera, a następnie moidfying WebService, aby użyć alternatywnej klasy Operacji.
Spędziłem nad tym kilka godzin, ale muszę przejść dalej. To zajmie prawdopodobnie dzień lub dwa.
Możesz być w stanie po prostu naprawić linię XMLEncoder i zrobić trochę łatania małp, aby użyć własnej klasy.
Dodam też, że jeśli przełączysz się na używanie RemoteObject / AMF z ColdFusion, zerowanie jest przekazywane bez problemów.
Aktualizacja z 16.11.2013 :
Mam jeszcze jeden najnowszy dodatek do mojego ostatniego komentarza na temat RemoteObject / AMF. Jeśli używasz ColdFusion 10; następnie właściwości z wartością zerową na obiekcie są usuwane z obiektu po stronie serwera. Musisz więc sprawdzić istnienie właściwości przed uzyskaniem do niej dostępu, w przeciwnym razie pojawi się błąd czasu wykonywania.
Sprawdź w ten sposób:
Jest to zmiana zachowania w stosunku do ColdFusion 9; gdzie właściwości zerowe zamieniłyby się w puste ciągi.
Edytuj 12.06.2013
Ponieważ pojawiło się pytanie o to, jak traktowane są wartości zerowe, oto krótka przykładowa aplikacja pokazująca, jak ciąg „null” będzie odnosił się do słowa zarezerwowanego null.
Dane wyjściowe śledzenia to:
źródło
content
jest ciąg"null"
, a „null” == null zwraca false, więc test zachowuje się zgodnie z przeznaczeniem. Zamiast tego uważam, że problem polega na tym, jak XML.appendChild obsługuje argument ciągu znaków i jak główny element XML zawierający tylko ciąg „null” może zostać przekonwertowany na literałnull
.true
jest pożądanym zachowaniem tutaj. Gdyby stało się inaczej, to odrzuciłoby ciąg „null” z procesu kodowania, co w rzeczywistości byłoby przyczyną problemu. Ponieważ jednak test się powiedzie, koder kontynuuje działanie, dopóki XML.appendChild nie porzuci go z powodu błędu przymusu.var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s);
do próbki kodu.Przetłumacz wszystkie znaki na ich odpowiedniki w postaci heksadecymalnej. W takim przypadku
Null
zostanie przekonwertowany naE;KC;C;
źródło
Tworzenie łańcucha
null
wartości w języku ActionScript da ciąg"NULL"
. Podejrzewam, że ktoś zdecydował, że dobrym pomysłem jest więc odkodowanie łańcucha,"NULL"
ponieważnull
powoduje to zerwanie, które tu widzicie - prawdopodobnie dlatego, że przechodzili oni przeznull
obiekty i dostawali ciągi do bazy danych, kiedy nie chcieli że (więc sprawdź też, czy nie ma tego rodzaju błędu).źródło
Jako hack możesz rozważyć specjalną obsługę po stronie klienta, konwersję łańcucha „Null” na coś, co nigdy się nie zdarzy, na przykład XXNULLXX i konwersję z powrotem na serwerze.
To nie jest ładne, ale może rozwiązać problem takiego przypadku granicznego.
źródło
Null
?Wydaje mi się, że implementacja Flex przez koder SOAP wydaje się niepoprawnie serializować wartości zerowe. Serializacja ich jako ciąg zerowy nie wydaje się dobrym rozwiązaniem. Wydaje się, że formalnie poprawna wersja ma wartość zerową, ponieważ:
Zatem wartość „Null” byłaby niczym innym jak prawidłowym łańcuchem, dokładnie tego, czego szukasz.
Wydaje mi się, że naprawienie tego w Apache Flex nie powinno być trudne. Polecam otwarcie problemu z Jira lub skontaktowanie się z facetami z listy mailingowej apache-flex. To jednak naprawiłoby tylko stronę klienta. Nie mogę powiedzieć, czy ColdFusion będzie w stanie pracować z wartościami zerowymi zakodowanymi w ten sposób.
Zobacz także wpis na blogu Radu Cotescu Jak wysyłać wartości zerowe w żądaniach soapUI .
źródło
null
poprawnie wartość true , ustawiającxsi:nil="true"
element. Wydaje się, że problem polega na tym, jakXML
sam typ ActionScript (nie koder) obsługuje ciąg"null"
.Jest to kludge, ale zakładając, że istnieje minimalna długość dla
SEARCHSTRING
, na przykład 2 znaki, parametr na drugi znak i przekazać go jako zamiast dwóch parametrów: a je z powrotem razem podczas wykonywania zapytania do bazy danych.substring
SEARCHSTRING
SEARCHSTRING1 ("Nu")
SEARCHSTRING2 ("ll").
Concatenate
źródło
n
,u
,l
mają specjalne semantykę w XML. „NULL” i „<! [CDATA [NULL]]>” są identyczne z analizatorem składni XML.NULL
, ale trzeba być pedantycznym<blah>null</blah>
i<blah><![CDATA[null]]>
nie być tym samym dla parsera XML. Oni powinni produkować takie same wyniki, jednak przepływ logika dla ich postępowania jest inna. Ten efekt wykorzystujemy jako obejście błędu w implementacji flex XML. Opowiadam się za tym w stosunku do innych podejść, ponieważ zachowuje on czytelność tekstu i nie ma skutków ubocznych dla innych parserów.