ActionScript 3'te “Null” (gerçek bir soyadı!) SOAP web hizmetine nasıl geçirilir


4635

Soyadı Null olan bir çalışanımız var. Çalışan sohbeti uygulamamız, bu soyadı arama terimi olarak kullanıldığında (şu anda oldukça sık olan) öldürülür. Alınan hata (teşekkürler Fiddler!):

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

Sevimli, ha?

Parametre türü string.

Ben kullanıyorum:

  • WSDL ( SABUN )
  • Esnek 3.5
  • ActionScript 3
  • ColdFusion 8

Web hizmetini bir ColdFusion sayfasından nesne olarak çağırırken hata oluşmadığını unutmayın .


6
Belirli bir problemde size bu kadar yardımcı olmayabilir, ancak SOAP 1.2 null değerlere izin verir, bkz. W3.org/TR/2001/WD-soap12-20010709/#_Toc478383513
JensG

6
Dave Null'u içerdiğini hissediyorum.
George Gibson

2
En azından Chuck Norris'i içermiyor. Neden ondan kodda uzak durmanız
gerekiyor

42
Çalışan adını değiştirmeyi düşündü mü?
Tatranskymedved

11
Gerçekten bir Pointer köpeği almayı ve ona NullPointer demeyi düşünmelidir .
Antonio Alvarez

Yanıtlar:


1108

Takip

İlk başta bunun nullzorlanan "null"bir test hatası olduğunu ve bir testin "null" == nullgeçtiğini düşündüm . Değil. Yakındım, ama çok, çok yanlıştım. Bunun için üzgünüm!

O zamandan beri wonderfl.net üzerinde çok uğraştım ve kod üzerinden izleme yaptım mx.rpc.xml.*. XMLEncoder(3.5 kaynağında) 1795 satırında setValue, XMLEncoding'in tümü

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

ki bu esasen aynıdır:

currentChild.appendChild("null");

Bu kod, orijinal kemanıma göre boş bir XML öğesi döndürüyor. Ama neden?

Sebep olmak

Hata raporu Justin Mclean yorumcu göre FLEX-33664 , şu suçlu (my son iki testler bakın olduğunu keman Bunu doğrulamak):

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
}

Ne zaman currentChild.appendChilddize geçirilir "null", metin ile bir kök XML öğesi için ilk dönüştürür o nullve sonra boş sabitin karşı o öğeyi test eder. Bu zayıf bir eşitlik testidir, bu nedenle null içeren XML null türüne zorlanır veya null türü "null" dizesini içeren bir kök xml öğesine zorlanır ve sınama muhtemelen başarısız olması gereken yerden geçer. Bir düzeltme, XML'yi (ya da gerçekten herhangi bir şeyi) "boş" olarak kontrol ederken her zaman katı eşitlik testlerini kullanmak olabilir .

Çözüm

Düşünebildiğim tek makul çözüm, bu hatayı ActionScript'in her lanet sürümünde düzeltmekten yoksun olarak, alanları "null" için test etmek ve CDATA değerleri olarak kaçmaktır .

CDATA değerleri, aksi takdirde kodlama / kod çözme sorunlarına neden olabilecek tüm metin değerini değiştirmenin en uygun yoludur. Örneğin onaltılık kodlama, tek tek karakterler içindir. Bir öğenin tüm metninden kaçarken CDATA değerleri tercih edilir. Bunun en büyük nedeni, insanın okunabilirliğini korumasıdır.


298

Açık xkcd notu , Bobby Tablolar web sitesi kullanıcı verilerinin yanlış yorumlanması (bu durumda, dize "null") SQL dahil olmak üzere çeşitli dilde sorgular kaçınmak için iyi bir tavsiye vardır ColdFusion .

Sorunun sorunun kaynağı olduğu açık değildir ve ilk cevaba yapılan bir açıklamada (parametrelerin bir yapıya gömülmesi) belirtilen çözüm verildiğinde, bunun başka bir şey olduğu muhtemel görünmektedir.


239

Sorun Flex'in SOAP kodlayıcısında olabilir. Flex uygulamanızda SOAP kodlayıcısını genişletmeyi deneyin ve null değerinin nasıl işlendiğini görmek için programda hata ayıklayın.

Benim tahminim, NaN (Sayı Değil) olarak geçti . Bu, SOAP mesajını bir zamanlar uyumsuz hale getirme işlemini bozacaktır (en önemlisi JBoss 5 sunucusunda ...). SOAP kodlayıcı genişletme ve NaN nasıl ele açık bir denetim gerçekleştirmeyi hatırlıyorum.


12
name = "Null" elbette faydalıdır ve NaN ile nasıl ilişkili olması gerektiğini anlamıyorum.
eckes

129

@ doc_180, sayılara odaklanması dışında doğru konsepte sahipken, orijinal posterin dizelerle ilgili sorunları vardı.

Çözüm mx.rpc.xml.XMLEncoderdosyayı değiştirmektir . Bu satır 121:

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

(Flex 4.5.1 SDK'ya baktım; satır numaraları diğer sürümlerde farklı olabilir.)

Temel olarak, 'içerik boş' olduğundan doğrulama başarısız olur ve bu nedenle argümanınız giden SOAP Paketine eklenmez; böylece eksik parametre hatasına neden olur.

Doğrulamayı kaldırmak için bu sınıfı genişletmeniz gerekir. Daha sonra, zincirin üstünde büyük bir kartopu var, değiştirilmiş XMLEncoder'ınızı kullanması için SOAPEncoder'ı değiştiriyor ve daha sonra değiştirilmiş SOAPEncoder'ınızı kullanmak için Operasyonu değiştiriyor ve daha sonra alternatif Operation sınıfınızı kullanmak için WebService'i nemlendiriyor.

Üzerinde birkaç saat geçirdim, ama devam etmem gerekiyor. Muhtemelen bir iki gün sürecek.

XMLEncoder hattını düzeltebilir ve kendi sınıfınızı kullanmak için bazı maymun yamaları yapabilirsiniz .

ColdFusion ile RemoteObject / AMF kullanmaya geçerseniz, null'un sorunsuz iletildiğini de ekleyeceğim.


16.11.2013 güncellemesi :

RemoteObject / AMF ile ilgili son yorumuma bir yenisi daha ekledim. ColdFusion 10 kullanıyorsanız; daha sonra bir nesne üzerinde null değeri olan özellikler sunucu tarafı nesnesinden kaldırılır. Bu nedenle, erişmeden önce özelliklerin varlığını kontrol etmeniz gerekir veya bir çalışma zamanı hatası alırsınız.

Şunun gibi kontrol et:

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

Bu, ColdFusion 9'daki davranış değişikliğidir; burada null özellikler boş dizgilere dönüşür.


Düzenle 12/6/2013

Null değerlerinin nasıl işlendiği hakkında bir soru olduğundan, burada "null" dizesinin ayrılmış null sözcüğü ile nasıl ilişkilendirileceğini göstermek için hızlı bir örnek uygulama verilmiştir.

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

İz çıktısı:

null dizesi,! = koşulunu kullanarak null ayrılmış sözcüğüne eşit değil

null dizesi, == koşulu kullanılarak null ayrılmış sözcüğüne eşit değil

null dizesi, === koşulunu kullanarak null ayrılmış sözcüğüne eşit değil


8
@ Reboog711 Çalışanın soyadı tam anlamıyla "Null" dizesidir, "Benim adım Pat Null". Cevabınız çalışanın soyadını geçemiyor. Sadece "Null" un Ben Burns tarafından tarif edilen appendChild () yöntemi tarafından null dil kavramına uygunsuz bir şekilde zorlandığı gerçeğini gizlersiniz. Sonuç hala sistemin Bay veya Bayan Null ile başa çıkamamasıdır.
Maxx Daymon

2
@MaxxDaymon Cevabımın gerçekte ne olduğunu yanlış yorumladığınızı düşünüyorum. Bir çözüm sunmuyor; daha ziyade sorunun neden oluştuğuna dair bir açıklama; ve Flex Code'daki ilgili kodu alıntılar. Daha yeni düzenlemem yanlış yerleştirilmiş olabilir; çünkü alternatif bir yaklaşımı tartışır ve asıl soru ile doğrudan ilgili değildir.
JeffryHouser

1
Doğru yoldasınız, ancak kodun bu noktasında contentdize vardır "null"ve "null" == null, false değerini döndürür, böylece test istendiği gibi çalışır. Bunun yerine, sorunun XML.appendChild'in bir dize argümanını nasıl işlediğinin ve yalnızca "null" dizesini içeren bir kök XML öğesinin bir değişmez değere nasıl zorlanabileceğinin bir karışımı olduğuna inanıyorum null.
Ben Burns

@ Reboog711 Kemanıma bir bak. "null"! = null` döndürme trueburada istenen davranıştır. Bunun tersi olursa, kodlama işleminden "null" dizesini atar, bu da sorunun nedeni olabilir. Ancak bu sınama başarılı olduğundan, XML.appendChild bir zorlama hatası nedeniyle silene kadar kodlayıcı devam eder.
Ben Burns

4
Telaşa gerek yok. Gerçek sorunu görmek istiyorsanız var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s);kod örneğinize ekleyin .
Ben Burns

65

Tüm karakterleri onaltılık varlık eşdeğerlerine çevirin. Bu durumda, Nulldönüştürülmüş olacaktır&#4E;&#75;&#6C;&#6C;


41
Lütfen bunu yapma. CDATA, tüm metin bloğundan kaçmanız gereken durumlarda kullanılmak üzere oluşturulmuştur.
Ben Burns

4
Yanılıyor olabilirim, ama sadece çözümünüz olmadığı için aşağı oylamayı düşünmüyorum , nasıl çalışması gerekiyordu. Ayrıca, sorunun sezgisel bir çözümü gerektirdiğini aklınızda bulundurmanız gerekir, çünkü yayınlanan çeşitli çözümlerin açıkça ortaya koyduğu gibi açık bir yol yoktur. Son olarak, CF bilmiyorum, bir kod çözücünün sadece <message><![CDATA[NULL Başarıldı> </message> 'un iç metnini <message> NULL </ message>? Öyleyse, CDATA gerçekten bir çözüm mü?
doogle

7
İndirdim çünkü bu bir anti-desen. Bu durumda hata CF'de değil, ActionScript'te. Ancak yine de iyi bir noktaya değindiniz. CDATA kodlaması için kemanıma bir test ekleyeceğim.
Ben Burns

51

ActionScript'te bir nulldeğerin dizilmesi dizeyi verir . Benim şüphe, birisi, bu nedenle, burada gördüğünüz kırılmaya neden olarak , dize kodunu çözmek için iyi bir fikir olduğuna karar vermiş olmasıdır - muhtemelen istemedikleri zaman nesnelere geçtikleri ve veritabanında dizeler aldıkları için yani (bu tür hataları da kontrol ettiğinizden emin olun)."NULL""NULL"nullnull


Evet, burada daralmak için daha fazla hata ayıklama gerektiren bir dizi olasılık var. 1) Burada kullanılan WSDL, bir dize değeri olarak "NULL" ile gerçek bir null (veya atlanmış) değer arasında ayrım yapacak kadar anlamlı mı? 2) Öyleyse, istemci soyadı doğru olarak kodlar mı (boş bir değişmez değil, bir dize olarak) 3) Öyleyse, hizmet "NULL" bir dize olarak doğru bir şekilde mi yorumlanıyor veya boş bir değere zorlanıyor mu?
pimlottc

39

Bir saldırı olarak, istemci tarafında özel bir işleme sahip olmayı, 'Null' dizesini hiç oluşmayacak bir şeye dönüştürmeyi düşünebilirsiniz, örneğin XXNULLXX ve sunucuya geri dönüş.

Güzel değil, ancak böyle bir sınır davası için sorunu çözebilir.


32
XXNULLXX de bir isim olabilir. Bilmiyorsun. Belki Endonezya'daki insanların soyadı yoktur ve gerektiğinde soyadı olarak XXX değişkenini kullanırlar.
gb.

3
Aynı kavram, ama veritabanındaki tüm adları güncelleyin ve önsöz sonra bazı karakter (1Null, 1Smith) ile. İstemcideki karakteri kaldırın. Tabii ki bu Reboog'un çözümünden daha çok akar işi olabilir.
bobpaul

14
@BenBurns Evet, ama ya çocuğuma isim vermek istersem &#78;&#117;&#108;&#108;?
Sirenler

@Sirens Sorun bu değil. İsmim "<"> ise, söylemeye gerek kalmadan "<& quot;" gt "şeklinde düzgün bir şekilde kaçmasını beklerim. Asıl sorun, bir uygulama adlar için bir kara liste kullanıyormuş gibi davranmasıdır.
Bay Lister

30

Sanırım Flex'in SOAP Encoder uygulamasının null değerleri yanlış serileştirdiği görülüyor. Onları bir String olarak serileştirmek Null iyi bir çözüm gibi görünmemektedir. Resmen doğru olan sürüm null değeri aşağıdaki gibi geçiriyor gibi görünüyor:

<childtag2 xsi:nil="true" />

Yani "Null" değeri, tam olarak aradığınız şey olan geçerli bir dizgiden başka bir şey değildir.

Sanırım bunu Apache Flex'te düzeltmek, bu kadar zor olmamalı. Bir Jira sorunu açmanızı veya apache-flex posta listesinin adamlarıyla iletişim kurmanızı öneririm. Ancak bu yalnızca istemci tarafını düzeltir. ColdFusion bu şekilde kodlanmış null değerleri ile çalışabilecek olup olmadığını söyleyemem.

Ayrıca bkz. Radu Cotescu'nun blog yazısı soapUI isteklerinde null değerler nasıl gönderilir .


6
Burada iyi bilgi var, bu yüzden aşağı oy vermeyeceğim, ama bir yorum yapmaya değer olduğunu düşündüm. Varsayılan olarak, XMLEncoder.as öğeyi nullayarlayarak gerçek değeri doğru şekilde kodlar xsi:nil="true". Sorun aslında ActionScript XMLtürünün kendisinin (kodlayıcı değil) dizeyi işleme biçiminde olduğu görülmektedir "null".
Ben Burns

22

Bu bir kludge, ama varsayarak orada için minimum boyda SEARCHSTRING2 karakter, örneğin, : ikinci karakterde parametre olduğunu ve iki parametre olarak geçmek ve veritabanına sorgu yürütülürken onları tekrar bir araya.substringSEARCHSTRINGSEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). Concatenate


32
Bu tür kludge'lardan kaçınmak için XML spesifikasyonuna CDATA eklendi.
Ben Burns

8
CDATA ile "Null" değerinden kaçmaya gerek yoktur, XML'de null anahtar sözcüğü diye bir şey yoktur.
eckes

6
@Eckes ile aynı fikirde. Neden bu kadar CDATA konuşması olduğunu anlamıyorum. CDATA yalnızca XML'de özel anlamı olan karakterlerden kaçmak için kullanışlıdır. hiçbiri: n, u, lXML özel anlamlara sahip. "NULL" ve "<! [CDATA [NULL]]>" "bir XML ayrıştırıcı ile aynıdır.
jasonkarns

9
@jasonkarns -% 100 dizgi / metin düğümü hakkında özel bir şey olmaması gerektiğini kabul ediyorum NULL, ancak bilgiç olmak <blah>null</blah>ve <blah><![CDATA[null]]>bir XML ayrıştırıcısı ile aynı olmamak. Onlar gerektiğini ancak bunları işlemek için mantık akış farklıdır, aynı sonucu verir. Esnek XML uygulamasındaki hataya geçici bir çözüm olarak sömürdüğümüz bu etkidir. Metnin okunabilirliğini koruduğu ve diğer ayrıştırıcılar için herhangi bir yan etkisi olmadığı için bunu diğer yaklaşımlar üzerinde savunuyorum.
Ben Burns
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.