ActionScript 3에서 "Null"(실제 성)을 SOAP 웹 서비스에 전달하는 방법


4635

성이 Null 인 직원이 있습니다. 직원 검색 응용 프로그램은 해당 성이 검색어로 사용될 때 종료됩니다 (현재는 자주 발생 함). 받은 오류 (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>

귀여워?

매개 변수 유형은 string입니다.

나는 사용하고있다 :

  • WSDL ( SOAP )
  • 플렉스 3.5
  • 액션 스크립트 3
  • ColdFusion 8

ColdFusion 페이지에서 객체로 웹 서비스를 호출 할 때 에러 발생 하지 않습니다 .


6
특정 문제에 대해서는 그다지 도움이되지는 않지만 SOAP 1.2는 nullable 값을 허용합니다. w3.org/TR/2001/WD-soap12-20010709/#_Toc478383513
JensG

6
Dave Null과 관련이 있다고 생각합니다.
조지 깁슨

2
적어도 척 노리스와는 관련이 없습니다. 코드에서 그를 멀리하는 이유는 다음과 같습니다. codesqueeze.com/…
SDsolar

42
직원이 자신의 이름을 바꾸는 것을 고려 했습니까?
Tatranskymedved

11
그는 실제로 포인터 개를 사서 그를 NullPointer라고 부릅니다.
안토니오 알바 레즈

답변:


1108

그것을 추적

처음에 나는 이것이 null강요되고 "null"테스트 "null" == null가 통과 하는 강압 버그라고 생각했습니다 . 그렇지 않습니다. 나는 가까웠지만 매우, 매우 틀렸다. 미안합니다!

그 후 wonderfl.net에서 많은 정보 를 수집 하고의 코드를 추적했습니다 mx.rpc.xml.*. XMLEncoder(3.5 소스의) 1795 행 에서 setValue모든 XMLEncoding이

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

본질적으로 다음과 같습니다.

currentChild.appendChild("null");

내 원래 바이올린에 따르면이 코드는 빈 XML 요소를 반환합니다. 그런데 왜?

원인

버그 리포트 FLEX-33664 에 대한 주석가 저스틴 맥클린 (Justin Mclean)에 따르면 , 다음은 범인입니다 (내 바이올린의 마지막 두 테스트를 참조하십시오 ).

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
}

currentChild.appendChild이 문자열에 전달 되면 "null"먼저 텍스트를 사용하여 루트 XML 요소로 변환 null한 다음 null 리터럴에 대해 해당 요소를 테스트합니다. 이것은 약한 동등성 테스트이므로 null을 포함하는 XML이 null 유형으로 강제 변환되거나 null 유형이 문자열 "null"을 포함하는 루트 xml 요소로 강제 변환되고 테스트가 실패 할 경우 통과합니다. 한 가지 수정은 "널 (nullness)"에 대해 XML (또는 실제로 무엇이든)을 확인할 때 항상 엄격한 동등성 테스트를 사용하는 것입니다.

해결책

내가 생각할 수있는 유일한 합리적인 해결 방법은 ActionScript의 모든 버전 에서이 버그를 수정하지 않고 "null"에 대한 필드를 테스트 하고 CDATA 값 으로 이스케이프 처리하는 것 입니다.

CDATA 값은 전체 텍스트 값을 변경하여 인코딩 / 디코딩 문제를 발생시키는 가장 적절한 방법입니다. 예를 들어 16 진 인코딩은 개별 문자를위한 것입니다. CDATA 값은 요소의 전체 텍스트를 이스케이프 처리 할 때 선호됩니다. 가장 큰 이유는 사람의 가독성을 유지하기 때문입니다.


298

XKCD 노트바비 테이블 웹 사이트는 사용자 데이터의 잘못된 해석 (이 경우, 문자열 "널") SQL에 포함 다양한 언어로 쿼리를 피하기위한 좋은 충고가 ColdFusion은 .

이것이 문제의 원인이라는 것은 확실하지 않으며, 첫 번째 답변에 대한 의견에 언급 된 해결책 (구조에 매개 변수 포함)이 다른 것으로 보인 것 같습니다.


239

Flex의 SOAP 인코더에 문제가있을 수 있습니다. Flex 애플리케이션에서 SOAP 인코더를 확장하고 프로그램을 디버그하여 널값이 어떻게 처리되는지 확인하십시오.

내 생각에, 그것은 NaN (숫자가 아님)으로 전달됩니다 . 이것은 SOAP 메시지 비 정렬 화 프로세스를 언젠가 (특히 JBoss 5 서버에서 ...) 엉망으로 만듭니다. SOAP 인코더를 확장하고 NaN 처리 방법을 명시 적으로 확인하는 것을 기억합니다.


12
name = "Null"은 물론 유용하며 NaN과 어떻게 관련이 있는지 알 수 없습니다.
eckes

129

@ doc_180은 숫자에 중점을 둔 것을 제외하고는 올바른 개념을 가지고 있었지만 원래 포스터에는 문자열에 문제가있었습니다.

해결책은 mx.rpc.xml.XMLEncoder파일 을 변경하는 것 입니다. 이것은 121 행입니다.

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

(Flex 4.5.1 SDK를 보았습니다. 행 번호는 다른 버전에서 다를 수 있습니다.)

기본적으로 'content is null'이므로 유효성 검사에 실패하므로 인수가 발신 SOAP 패킷에 추가되지 않습니다. 따라서 누락 된 매개 변수 오류가 발생합니다.

유효성 검사를 제거하려면이 클래스를 확장해야합니다. 그런 다음 체인에 큰 눈덩이가있어 수정 된 XMLEncoder를 사용하도록 SOAPEncoder를 수정 한 다음 수정 된 SOAPEncoder를 사용하도록 Operation을 수정 한 다음 WebService를 moidfying하여 대체 Operation 클래스를 사용합니다.

나는 그것에 몇 시간을 보냈지 만 계속해야합니다. 아마 하루나 이틀 걸릴 것입니다.

XMLEncoder 줄을 수정하고 자신의 클래스를 사용하기 위해 원숭이 패치 를 수행 할 수 있습니다.

또한 ColdFusion과 함께 RemoteObject / AMF를 사용하도록 전환하면 문제없이 null이 전달됩니다.


2013 년 11 월 16 일 업데이트 :

RemoteObject / AMF에 대한 마지막 의견에 최근에 추가 된 내용이 하나 더 있습니다. ColdFusion 10을 사용하는 경우; 그런 다음 개체에 null 값이있는 속성이 서버 쪽 개체에서 제거됩니다. 따라서 속성에 액세스하기 전에 속성 존재를 확인해야합니다. 그렇지 않으면 런타임 오류가 발생합니다.

다음과 같이 확인하십시오.

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

이것은 ColdFusion 9에서 변경된 동작입니다. 여기서 null 속성은 빈 문자열로 바뀝니다.


2013 년 12 월 6 일 수정

널이 처리되는 방법에 대한 질문이 있으므로 다음은 문자열 "널"이 예약어 인 널과 어떻게 관련되는지를 보여주는 빠른 샘플 애플리케이션입니다.

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

추적 출력은 다음과 같습니다.

null 문자열은! = 조건을 사용하여 null 예약어와 같지 않습니다

== 조건을 사용하여 널 문자열이 널 예약어와 같지 않음

=== 조건을 사용하여 널 문자열이 널 예약어와 같지 않음


8
@ Reboog711 직원의 성은 "내 이름은 Pat Null입니다"와 같이 문자 그대로 "Null"입니다. 답변이 직원의 성을 통과하지 못했습니다. 당신은 벤 번즈 (Ben Burns)에 의해 기술 된 appendChild () 메소드에 의해 "Null"이 null의 언어 개념으로 부적절하게 강제되어 있다는 사실을 숨 깁니다. 그 결과 시스템이 여전히 Mr. 또는 Ms. Null을 처리하지 못합니다.
Maxx Daymon

2
@ MaxxDaymon 내 대답이 실제로 무엇인지 오해한다고 생각합니다. 해결책이 없습니다. 오히려 문제가 발생하는 이유에 대한 설명; Flex Framework에서 관련 코드를 인용합니다. 내 최근 편집 내용이 잘못 배치되었을 수 있습니다. 대체 접근법을 논의하고 원래 질문과 직접적으로 관련이 없습니다.
JeffryHouser

1
당신은 올바른 길을 가고 있지만 코드의 그 시점에서 content문자열은 "null""null"== null이 false를 반환하므로 테스트가 의도 한대로 작동합니다. 대신 문제는 XML.appendChild가 문자열 인수를 처리하는 방법과 문자열 "null"만 포함하는 루트 XML 요소를 리터럴로 강제 변환하는 방법이 혼합되어 있다고 생각합니다 null.
Ben Burns

@ Reboog711 내 바이올린을 살펴보십시오. "null"! = null` 리턴 true은 원하는 동작입니다. 반대로 발생하면 인코딩 프로세스에서 문자열 "널"을 버리고 실제로 문제의 원인이됩니다. 그러나이 테스트가 성공했기 때문에 XML.appendChild가 강제 버그로 인해 폐기 할 때까지 인코더는 계속 진행합니다.
Ben Burns

4
걱정 마. 실제 문제 var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s);를 보려면 코드 샘플에 추가 하십시오.
Ben Burns

65

모든 문자를 16 진법으로 변환하십시오. 이 경우, Null로 변환 될 것이다&#4E;&#75;&#6C;&#6C;


41
이러지 마십시오. CDATA는 전체 텍스트 블록을 이스케이프해야하는 경우에 사용하기 위해 만들어졌습니다.
Ben Burns

4
나는 틀릴 수 있지만, 그것이 당신의 해결책이 아니기 때문에 다운 투표 하는 것이 그것이 작동하는 방식 이라고 생각하지 않습니다 . 또한 게시 된 다양한 솔루션에서 알 수 있듯이 명백한 방법이 없기 때문에 휴리스틱 솔루션이 필요하다는 점을 염두에 두어야합니다. 마지막으로 CF를 모른다는 점을 명심하고 디코더가 <message> <! [CDATA [NULL]]> </ message>의 내부 텍스트를 <message> NULL </의 내부 텍스트와 동일시하는 것은 아닙니다. 메시지>? 그렇다면 CDATA는 실제로 솔루션입니까?
doogle

7
이것은 안티 패턴이기 때문에 다운 투표했습니다. 이 경우 버그는 CF가 아니라 ActionScript에 있습니다. 그럼에도 불구하고, 당신은 좋은 지적을 제기합니다. CDATA 인코딩을 위해 바이올린에 테스트를 추가합니다.
Ben Burns

51

ActionScript 에서 null값을 문자열 화 하면 문자열이 제공됩니다 . 내 의심은 누군가가 문자열을 로 디코딩하는 것이 좋은 생각이라고 결정했다는 것입니다. 아마도 여기에서 보이는 파손을 일으 킵니다. 아마도 객체를 원하지 않고 데이터베이스에서 문자열을 얻었 기 때문에 (그래서 그런 종류의 버그도 확인하십시오)."NULL""NULL"nullnull


예, 여기에는 범위를 좁히기 위해 더 많은 디버깅이 필요한 여러 가지 가능성이 있습니다. 1) 여기서 사용 된 WSDL은 문자열 값으로 "NULL"과 실제 널 (또는 생략) 값을 구별하기에 충분히 표현 적인가? 2) 그렇다면 클라이언트가 성을 올바르게 인코딩하고 (널 리터럴이 아닌 문자열로) 3) 그렇다면 서비스가 "NULL"을 문자열로 올바르게 해석하거나 널값으로 강제 변환합니까?
pimlottc

39

해킹으로 클라이언트 측에서 특수 처리를 수행하여 'Null'문자열을 XXNULLXX와 같이 절대 발생하지 않는 것으로 변환하고 서버에서 다시 변환하는 것을 고려할 수 있습니다.

그것은 예쁘지는 않지만 그러한 경계 사건의 문제를 해결할 수 있습니다.


32
XXNULLXX도 이름이 될 수 있습니다. 당신은 모른다. 아마도 인도네시아 사람들은 성을 가지고 있지 않고 필요할 때 XXX의 변형을 성을 사용합니다.
gb.

3
동일한 개념이지만 데이터베이스의 모든 이름을 업데이트 한 다음 일부 문자 (1Null, 1Smith)로 머리말을 업데이트하십시오. 클라이언트에서 해당 문자를 제거하십시오. 물론 이것은 Reboog의 솔루션보다 진드기 일 수 있습니다.
bobpaul

14
@ BenBurns 그래,하지만 내 아이의 이름을 지정하려면 어떻게해야 &#78;&#117;&#108;&#108;합니까?
사이렌

@Sirens 문제가 아닙니다. 내 이름이 "<"이면, "& lt;"& gt;로 제대로 이스케이프 될 것으로 예상된다. 실제 문제는 이름에 블랙리스트를 사용하는 것처럼 동작하는 응용 프로그램에 있습니다.
Mr Lister

30

Flex의 SOAP Encoder 구현은 null 값을 잘못 직렬화하는 것 같습니다. 그것들을 String Null로 직렬화하는 것은 좋은 해결책이 아닌 것 같습니다. 공식적으로 올바른 버전은 다음과 같이 null 값을 전달하는 것으로 보입니다.

<childtag2 xsi:nil="true" />

따라서 "Null"의 값은 올바른 문자열 일뿐입니다. 바로 이것이 바로 당신이 찾고있는 것입니다.

Apache Flex 에서이 문제를 해결하는 것이 그렇게 어렵지 않아야한다고 생각합니다. Jira 이슈를 열거 나 아파치 플렉스 메일 링리스트에게 연락하는 것이 좋습니다. 그러나 이것은 클라이언트 측만 수정합니다. ColdFusion이이 방법으로 인코딩 된 null 값으로 작동 할 수 있는지 말할 수 없습니다.

Radu Cotescu의 블로그 게시물 soapUI 요청에서 null 값을 보내는 방법을 참조하십시오 .


6
여기에 좋은 정보가 있으므로 공감하지는 않지만 의견이 가치가 있다고 생각했습니다. 기본적으로 XMLEncoder.as는 요소 null를 설정 xsi:nil="true"하여 실제로 실제 값을 올바르게 인코딩합니다 . 실제로이 문제는 ActionScript XML유형 자체 (인코더가 아님)가 문자열을 처리하는 방식에있는 것으로 보입니다 "null".
Ben Burns

22

그것은 kludge,하지만 가정이에 대한 최소 길이의 SEARCHSTRING2 문자, 예를 들어, : 두 번째 문자에서 매개 변수 대신 두 개의 매개 변수로 전달 하고 데이터베이스에 쿼리를 실행할 때 그들을 다시 함께.substringSEARCHSTRINGSEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). Concatenate


32
이러한 유형의 결점을 피하기 위해 CDATA가 XML 사양에 추가되었습니다.
Ben Burns

8
CDATA를 사용하여 "Null"을 이스케이프 처리 할 필요가 없으며 XML의 null 키워드와 같은 것은 없습니다.
eckes

6
@eckes에 동의하십시오. CDATA에 대한이 모든 이야기가 왜 있는지 이해가되지 않습니다. CDATA는 XML에서 특별한 의미가있는 문자를 이스케이프하는 데만 유용합니다. 아무도 : n, u, lXML에서 특별한 의미가 없습니다. "NULL"및 "<! [CDATA [NULL]]>"은 XML 파서와 동일합니다.
jasonkarns

9
@jasonkarns는 - 내가 거기 있음을 100 % 동의 한다 문자열 / 텍스트 노드에 대해 아무것도 특별 할 수 NULL있지만, 학자가 될, <blah>null</blah>그리고 <blah><![CDATA[null]]>XML 파서에 동일하지 않습니다 있습니다. 그들은 해야 하지만이를 처리하기위한 논리 흐름이 다른, 동일한 결과를 생성합니다. Flex XML 구현의 버그에 대한 임시 해결책으로 활용하는 것이이 효과입니다. 나는 텍스트의 가독성을 유지하고 다른 파서에는 부작용이 없기 때문에 다른 접근 방식보다 이것을 옹호합니다.
Ben Burns
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.